springboot进阶学习(五)springboot集成websocket

导读:本篇文章讲解 springboot进阶学习(五)springboot集成websocket,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

springboot集成websocket

websocket能干什么

  • 主动从服务端向客户端传递消息,这个可以实现我们定时获取后台信息的需求。前台页面不需要定期刷新,后台可以定时或者有更新的时候向前台传递信息。
  • 可以实现类似聊天室的需求。

基本实例

  1. 引入所需的jar包
<!-- websocket -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
  1. 创建一个config,开启websocket支持
@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter(){
        return new ServerEndpointExporter();
    }
}
  1. 创建一个websocket的服务端WebSocketServer
@ServerEndpoint("/websocket")
@Component
@Slf4j
public class WebSocketServer {
    //静态变量,用来记录当前在线连接数。
    private static int onlineCount = 0;
    //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
    private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<>();
    //与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;
    //接收sid
    private String userId ="";

    /**
     * 连接建立成功调用的方法
     * @param session
     * @param userId
     */
    @OnOpen
    public void onOpen(Session session,@PathParam("userId") String userId) {
        this.session = session;
        this.userId =userId;
        webSocketSet.add(this);     //加入set中
        addOnlineCount();           //在线数加1
        log.info("有新窗口开始监听:"+userId+",当前在线人数为" + getOnlineCount());
        try {
            //向客户端发送消息
            sendMessage("连接成功");
        } catch (IOException e) {
            log.error("websocket IO异常" + e.getMessage());
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        webSocketSet.remove(this);  //从set中删除
        subOnlineCount();           //在线数减1
        log.info("有一连接关闭!当前在线人数为" + getOnlineCount());
    }

    /**
     * 收到客户端消息后调用的方法
     * @param message 客户端发送过来的消息内容
     * @param session
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        //接收到消息后,在这里可以处理自己的业务
        log.info("收到来自窗口"+ userId +"的信息:"+message);
        //如果是一个聊天室,可以在这里群发消息(这个只是举例,具体业务逻辑看自己的需要)
        for (WebSocketServer item : webSocketSet) {
            try {
                item.sendMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 发生错误时调用的方法
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("发生错误:"+ error.getMessage());
        error.printStackTrace();
    }
    /**
     * 服务器主动推送到客户端,这个客户端时当前连接的客户端(this.session)
     */
    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }


    /**
     * 群发自定义消息
     * @param message
     * @throws IOException
     */
    public static void sendInfo(String message) throws IOException {
        for (WebSocketServer item : webSocketSet) {
            try {
                item.sendMessage(message);
            } catch (IOException e) {
                continue;
            }
        }
    }

    /**
     * 群发一个对象信息
     * @param studentList
     */
    public static void sendInfo(List<Student> studentList){
        for (WebSocketServer item : webSocketSet) {
            try {
                item.sendMessage(JSON.toJSONString(studentList));
            } catch (IOException e) {
                continue;
            }
        }
    }

    private static synchronized int getOnlineCount() {
        return onlineCount;
    }

    private static synchronized void addOnlineCount() {
        WebSocketServer.onlineCount++;
    }

    private static synchronized void subOnlineCount() {
        WebSocketServer.onlineCount--;
    }
}
  • 可以把这个WebSocketServer当成是controller一样使用,但是他是ws协议,不是http协议,所以要连接这个服务器端就要使用
    ws://ip:port/projectName/@ServerEndpoint的格式,例如我们的示例是ws://127.0.0.1:8088/moyundong/websocket
  • @ServerEndpoint(“/imserver/{userId}”)类似controller里面的@RequestMapping,也可以后面带参数,例如@ServerEndpoint(“/websocket/{userId}”)
  • WebSocketServer里面包含接收到消息的方法,发送给客户端的方法,关闭连接等等许多方法,大家根据需要添加自己的业务
  • 使用CopyOnWriteArraySet来存放每个连接的实例,方便我们给全部或者指定客户端发送消息
  1. 创建一个客户端测试(index.jsp页面)
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
    <title>WebSocket 聊天室</title>
</head>
<body>
<script type="text/javascript">
    var socket;
    if (!window.WebSocket) {
        window.WebSocket = window.MozWebSocket;
    }
    if (window.WebSocket) {
        socket = new WebSocket("ws://127.0.0.1:8088/moyundong/websocket");
        socket.onmessage = function(event) {
            var ta = document.getElementById('responseText');
            ta.value = ta.value + '\n' + event.data
        };
        socket.onopen = function(event) {
            var ta = document.getElementById('responseText');
            ta.value = "连接开启!";
        };
        socket.onclose = function(event) {
            var ta = document.getElementById('responseText');
            ta.value = ta.value + "连接被关闭";
        };
    } else {
        alert("你的浏览器不支持 WebSocket!");
    }

    function send(message) {
        if (!window.WebSocket) {
            return;
        }
        if (socket.readyState == WebSocket.OPEN) {
            socket.send(message);
        } else {
            alert("连接没有开启.");
        }
    }
</script>
<form οnsubmit="return false;">
    <h3>WebSocket 聊天室:</h3>
    <textarea id="responseText" style="width: 500px; height: 300px;"></textarea>
    <br>
    <input type="text" name="message"  style="width: 300px" value='随便输入:'>
    <input type="button" value="发送消息" οnclick="send(this.form.message.value)">
    <input type="button" οnclick="javascript:document.getElementById('responseText').value=''" value="清空聊天记录">
</form>
</body>
</html>

这是一个简易聊天室的例子

  • new WebSocket("ws://127.0.0.1:8088/moyundong/websocket");创建一个连接
  • socket.onmessage当客户端接收到消息时的方法,可以处理自己的业务
  • socket.onopen连接成功后的方法
  • socket.onclose连接断开后的方法
  1. 在浏览器运行http://localhost:8088/moyundong/index.jsp就可以客气客户端了
    ::: tip 提示
    这个只是最基本的例子,连接的时候也没有加userId,但是原理就是这些,大家可以根据自己的业务需求去拓展。
    :::

websocket加定时任务

前面我们学习了定时任务,我们可以把定时任务和websocket结合起来,这样可以实现定时向客户端发送特点信息,并且客户端页面也不用实时发送请求查询后台信息。
有这方面需求的朋友可以去试下。原理就是在定时任务里面调用WebSocketServer的静态方法就可以了

1介绍
2springboot定时任务
3springboot定时任务配置详解
4springboot动态定时任务
5springboot集成websocket
6springboot多数据源
7springboot配置druid监听
8springboot自定义注解
9springboot常见注解详解
10springboot接收参数详解
11springboot验证机制@Valid和@Validated
12springboot集成Swagger2
13springboot集成swagger-bootstrap-ui
14springboot集成shiro
15springboot集成shiro(二)
16springboot集成jwt
17springboot集成ActiveMQ
18springboot缓存机制

🍉🍉🍉 欢迎大家来博客了解更多内容:java乐园 🍉🍉🍉

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/13511.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!