美文网首页JavaSpringBoot
SpringBoot实现websocket实现聊天

SpringBoot实现websocket实现聊天

作者: 花伤情犹在 | 来源:发表于2022-03-26 14:00 被阅读0次

    Maven依赖:

             <!--screw依赖-->
            <dependency>
                <groupId>cn.smallbun.screw</groupId>
                <artifactId>screw-core</artifactId>
                <version>1.0.2</version>
            </dependency>
            <!--hutools-->
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>5.7.12</version>
            </dependency>
            <!--javaee-api-->
            <dependency>
                <groupId>javax</groupId>
                <artifactId>javaee-api</artifactId>
                <version>7.0</version>
                <scope>provided</scope>
            </dependency>
            <!--json-lib-->
            <dependency>
                <groupId>net.sf.json-lib</groupId>
                <artifactId>json-lib</artifactId>
                <version>2.4</version>
                <classifier>jdk15</classifier>
            </dependency>
            <!--websocket-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-websocket</artifactId>
            </dependency>
    

    在线模拟websocket请求工具:
    https://www.bejson.com/httputil/websocket/

    websocketConfig:

    
    /**
     * websocket配置
     */
    @Configuration
    public class websocketConfig {
        /**
         * 服务器端点导出器
         * @return
         */
        @Bean
        public ServerEndpointExporter serverEndpointExporter(){
            return new ServerEndpointExporter();
        }
    }
    
    

    WebSocketOneToOne:

    /**
     * @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
     *                 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
     */
    @RestController
    @ServerEndpoint(value = "/webSocketOneToOne/{param}")
    public class WebSocketOneToOne {
    
        // 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
        private static int onlineCount;
        //实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key为用户标识
        private static Map<String,WebSocketOneToOne> connections = new ConcurrentHashMap<>();
        // 与某个客户端的连接会话,需要通过它来给客户端发送数据
        private Session session;
        //角色
        private String role;
        //socketid
        private String socketId;
    
        /**
         * 连接建立成功调用的方法
         *
         * @param session
         *            可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
         */
        @OnOpen
        public void onOpen(@PathParam("param") String param, Session session) {
            this.session = session;
            String[] arr = param.split(",");
            this.role = arr[0];             //用户标识
            this.socketId = arr[1];         //会话标识
            connections.put(role,this);     //添加到map中
            addOnlineCount();               // 在线数加
            System.out.println("有新连接加入!新用户:"+role+",当前在线人数为" + getOnlineCount());
        }
    
        /**
         * 连接关闭调用的方法
         */
        @OnClose
        public void onClose() {
            connections.remove(role);  // 从map中移除
            subOnlineCount();          // 在线数减
            System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
        }
    
        /**
         * 收到客户端消息后调用的方法
         *
         * @param message
         *            客户端发送过来的消息
         * @param session
         *            可选的参数
         */
        @OnMessage
        public void onMessage(String message, Session session) {
            System.out.println("来自客户端的消息:" + message);
            JSONObject json=JSONObject.fromObject(message);
            String string = null;  //需要发送的信息
            String to = null;      //发送对象的用户标识
            if(json.has("message")){
                string = (String) json.get("message");
            }
            if(json.has("role")){
                to = (String) json.get("role");
            }
            send(string,role,to,socketId);
        }
    
        /**
         * 发生错误时调用
         *
         * @param session
         * @param error
         */
        @OnError
        public void onError(Session session, Throwable error) {
            System.out.println("发生错误");
            error.printStackTrace();
        }
    
    
        //发送给指定角色
        public void send(String msg,String from,String to,String socketId){
            try {
                //to指定用户
                WebSocketOneToOne con = connections.get(to);
                if(con!=null){
                    if(socketId==con.socketId||con.socketId.equals(socketId)){
                        con.session.getBasicRemote().sendText(from+"说11:"+msg);
                    }
    
                }
                //from具体用户
                WebSocketOneToOne confrom = connections.get(from);
                if(confrom!=null){
                    if(socketId==confrom.socketId||confrom.socketId.equals(socketId)){
                        confrom.session.getBasicRemote().sendText(from+"说:"+msg);
                    }
    
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
        /**
         * 获取在线人数
         * @return
         */
        public static synchronized int getOnlineCount() {
            return onlineCount;
        }
    
        /**
         * 在线数添加
         */
        public static synchronized void addOnlineCount() {
            WebSocketOneToOne.onlineCount++;
        }
    
        public static synchronized void subOnlineCount() {
            WebSocketOneToOne.onlineCount--;
        }
    }
    

    用户1

    连接请求:

    ws://127.0.0.1:8888/webSocketOneToOne/1,520
    

    JSON消息内容:

    { 'message': '2号用户你好', 'role': '2', 'socketId': '520' }
    

    用户2

    连接请求:

    ws://127.0.0.1:8888/webSocketOneToOne/2,520
    

    JSON消息内容:

    { 'message': '1号用户你好', 'role': '1', 'socketId': '520' }
    

    理解性

    message:需要发送的消息内容
    role:需要发送的对象
    socketId:需要发送的房间

    相关文章

      网友评论

        本文标题:SpringBoot实现websocket实现聊天

        本文链接:https://www.haomeiwen.com/subject/juedjrtx.html