• Spring Boot 系列


    在实现消息推送的项目中往往需要WebSocket,以下简单讲解在Spring boot 中使用 WebSocket。

    1、pom.xml 中引入 spring-boot-starter-websocket

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>
    

    2、往spring容器中注入 ServerEndpointExporter

    package com.sam.conf;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.socket.server.standard.ServerEndpointExporter;
    
    /**
     * WebSocket配置
     * <p>
     * 自动注册使用了@ServerEndpoint注解声明的Websocket endpoint
     * 要注意,如果使用独立的servlet容器,而不是直接使用springboot的内置容器,就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理。
     *
     * @author sam
     * @since 2017/9/13
     */
    
    @Configuration
    public class WebSocketConfig {
        @Bean
        public ServerEndpointExporter serverEndpointExporter() {
            return new ServerEndpointExporter();
        }
    
    }
    
    

    3、Endpoint 具体实现

    package com.sam.websocket;
    
    import org.springframework.stereotype.Component;
    
    import javax.websocket.*;
    import javax.websocket.server.PathParam;
    import javax.websocket.server.ServerEndpoint;
    import java.io.IOException;
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    
    /**
     * ServerEndpoint
     * <p>
     * 使用springboot的唯一区别是要@Component声明下,而使用独立容器是由容器自己管理websocket的,但在springboot中连容器都是spring管理的。
     * <p>
     * 虽然@Component默认是单例模式的,但springboot还是会为每个websocket连接初始化一个bean,所以可以用一个静态set保存起来。
     *
     * @author sam
     * @since 2017/9/13
     */
    @ServerEndpoint("/ws/chatRoom/{userName}") //WebSocket客户端建立连接的地址
    @Component
    public class ChatRoomServerEndpoint {
    
        /**
         * 存活的session集合(使用线程安全的map保存)
         */
        private static Map<String, Session> livingSessions = new ConcurrentHashMap<>();
    
        /**
         * 建立连接的回调方法
         *
         * @param session  与客户端的WebSocket连接会话
         * @param userName 用户名,WebSocket支持路径参数
         */
        @OnOpen
        public void onOpen(Session session, @PathParam("userName") String userName) {
            livingSessions.put(session.getId(), session);
            sendMessageToAll(userName + " 加入聊天室");
        }
    
        /**
         * 收到客户端消息的回调方法
         *
         * @param message 客户端传过来的消息
         * @param session 对应的session
         */
        @OnMessage
        public void onMessage(String message, Session session, @PathParam("userName") String userName) {
            sendMessageToAll(userName + " : " + message);
        }
    
    
        /**
         * 发生错误的回调方法
         *
         * @param session
         * @param error
         */
        @OnError
        public void onError(Session session, Throwable error) {
            System.out.println("发生错误");
            error.printStackTrace();
        }
    
        /**
         * 关闭连接的回调方法
         */
        @OnClose
        public void onClose(Session session, @PathParam("userName") String userName) {
            livingSessions.remove(session.getId());
            sendMessageToAll(userName + " 退出聊天室");
        }
    
    
        /**
         * 单独发送消息
         *
         * @param session
         * @param message
         */
        public void sendMessage(Session session, String message) {
            try {
                session.getBasicRemote().sendText(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 群发消息
         *
         * @param message
         */
        public void sendMessageToAll(String message) {
            livingSessions.forEach((sessionId, session) -> {
                sendMessage(session, message);
            });
        }
    
    }
    
    

    4、前端页面实现

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>聊天室</title>
        <script src="http://code.jquery.com/jquery-1.8.0.min.js"></script>
    </head>
    <body>
    <h1>聊天室</h1>
    
    <textarea id="chat_content" readonly="readonly" cols="100" rows="9">
    
    </textarea>
    
    <br>
    
    用户:<input type="text" id="user_name" value="" name="userName"/>
    <button id="btn_join">加入聊天室</button>
    <button id="btn_exit">退出聊天室</button>
    
    <br>
    
    消息:<input type="text" id="send_text" value="" name="sendText"/>
    <button id="btn_send">发送</button>
    
    </body>
    </html>
    
    <script>
        $(function () {
    
            var prefixUrl = 'ws://127.0.0.1:8080/ws/chatRoom/';
    
            var ws;//WebSocket连接对象
    
            //判断当前浏览器是否支持WebSocket
            if (!('WebSocket' in window)) {
                alert('Not support websocket');
            }
    
            $('#btn_join').click(function () {
    
                var userName = $('#user_name').val();
    
                //创建WebSocket连接对象
                ws = new WebSocket(prefixUrl + userName);
    
                //连接成功建立的回调方法
                ws.onopen = function (event) {
                    console.log('建立连接')
                }
    
                //接收到消息的回调方法
                ws.onmessage = function (event) {
                    console.log('接收到内容:' + event.data)
                    $('#chat_content').append(event.data + '
    ')
                }
    
                //连接发生错误的回调方法
                ws.onerror = function (event) {
                    console.log('发生错误')
                }
    
                //连接关闭的回调方法
                ws.onclose = function (event) {
                    console.log('关闭连接')
                }
    
            })
    
            //发送消息
            function sendMessage(message) {
                ws.send(message);
            }
    
            //关闭连接
            function closeWebSocket() {
                ws.close();
            }
    
            //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
            window.onbeforeunload = function () {
                wx.close();
            }
    
    
            //发送消息
            $('#btn_send').click(function () {
                sendMessage($('#send_text').val())
            })
    
            //点击退出聊天室
            $('#btn_exit').click(function () {
                closeWebSocket();
            })
        })
    </script>
    

    以上为完整demo内容。

    推荐: 阿里技术-小马哥讲解WebSocket
  • 相关阅读:
    python—打开图像文件报错
    CTFshow萌新赛-萌新福利
    微信小程序bug
    微信小程序
    架构
    命令行
    MyBatis
    avalon
    并发测试工具
    less
  • 原文地址:https://www.cnblogs.com/magicalSam/p/7522060.html
Copyright © 2020-2023  润新知