• SpringBoot使用websocket


    一、整合websocket

    <!-- 引入websocket依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>
    

    开启websocket功能

    @Configuration
    public class WebSocketConfig {
        @Bean
        public ServerEndpointExporter serverEndpointExporter() {
            return new ServerEndpointExporter();
        }
    }
    

    websocket配置类

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.socket.server.standard.ServerEndpointExporter;
    
    @Configuration
    public class WebSocketConfig {
        /**
         * ServerEndpointExporter 作用
         *
         * 这个Bean会自动注册使用@ServerEndpoint注解声明的websocket endpoint
         *
         * @return
         */
        @Bean
        public ServerEndpointExporter serverEndpointExporter() {
            return new ServerEndpointExporter();
        }
    }
    

    websocket核心类

    package com.winmine.WebSocket.service;
    
    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.concurrent.ConcurrentHashMap;
    import java.util.concurrent.atomic.AtomicInteger;
    
    @ServerEndpoint("/webSocket/{sid}")
    @Component
    public class WebSocketServer {
       //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
       private static AtomicInteger onlineNum = new AtomicInteger();
    
       //concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象。
       private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();
    
       //发送消息
       public void sendMessage(Session session, String message) throws IOException {
           if(session != null){
               synchronized (session) {
    //                System.out.println("发送数据:" + message);
                   session.getBasicRemote().sendText(message);
               }
           }
       }
       //给指定用户发送信息
       public void sendInfo(String userName, String message){
           Session session = sessionPools.get(userName);
           try {
               sendMessage(session, message);
           }catch (Exception e){
               e.printStackTrace();
           }
       }
    
       //建立连接成功调用
       @OnOpen
       public void onOpen(Session session, @PathParam(value = "sid") String userName){
           sessionPools.put(userName, session);
           addOnlineCount();
           System.out.println(userName + "加入webSocket!当前人数为" + onlineNum);
           try {
               sendMessage(session, "欢迎" + userName + "加入连接!");
           } catch (IOException e) {
               e.printStackTrace();
           }
       }
    
       //关闭连接时调用
       @OnClose
       public void onClose(@PathParam(value = "sid") String userName){
           sessionPools.remove(userName);
           subOnlineCount();
           System.out.println(userName + "断开webSocket连接!当前人数为" + onlineNum);
       }
    
       //收到客户端信息
       @OnMessage
       public void onMessage(String message) throws IOException{
           message = "客户端:" + message + ",已收到";
           System.out.println(message);
           for (Session session: sessionPools.values()) {
               try {
                   sendMessage(session, message);
               } catch(Exception e){
                   e.printStackTrace();
                   continue;
               }
           }
       }
    
       //错误时调用
       @OnError
       public void onError(Session session, Throwable throwable){
           System.out.println("发生错误");
           throwable.printStackTrace();
       }
    
       public static void addOnlineCount(){
           onlineNum.incrementAndGet();
       }
    
       public static void subOnlineCount() {
           onlineNum.decrementAndGet();
       }
    
    }
    
    

    在Controller中跳转页面

    import com.winmine.WebSocket.service.WebSocketServer;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.servlet.ModelAndView;
    
    import java.util.HashMap;
    import java.util.Map;
    
    @Controller
    public class SocketController {
    
        @Autowired
        private WebSocketServer webSocketServer;
    
        @RequestMapping("/index")
        public String index() {
            return "index";
        }
    
        @GetMapping("/webSocket")
        public ModelAndView socket() {
            ModelAndView mav=new ModelAndView("/webSocket");
    //        mav.addObject("userId", userId);
            return mav;
        }
    
    
    }
    

    前端代码在webSocket.html中

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>WebSocket</title>
    
    </head>
    <body>
    <h3>hello socket</h3>
    <p>【userId】:<div><input id="userId" name="userId" type="text" value="10"></div>
    <p>【toUserId】:<div><input id="toUserId" name="toUserId" type="text" value="20"></div>
    <p>【toUserId】:<div><input id="contentText" name="contentText" type="text" value="hello websocket"></div>
    <p>操作:<div><a onclick="openSocket()">开启socket</a></div>
    <p>【操作】:<div><a onclick="sendMessage()">发送消息</a></div>
    </body>
    <script>
        
    
        var socket;
        function openSocket() {
            if(typeof(WebSocket) == "undefined") {
                console.log("您的浏览器不支持WebSocket");
            }else{
                console.log("您的浏览器支持WebSocket");
                //实现化WebSocket对象,指定要连接的服务器地址与端口  建立连接
                var userId = document.getElementById('userId').value;
                // var socketUrl="ws://127.0.0.1:22599/webSocket/"+userId;
                var socketUrl="ws://192.168.0.231:22599/webSocket/"+userId;
                console.log(socketUrl);
                if(socket!=null){
                    socket.close();
                    socket=null;
                }
                socket = new WebSocket(socketUrl);
                //打开事件
                socket.onopen = function() {
                    console.log("websocket已打开");
                    //socket.send("这是来自客户端的消息" + location.href + new Date());
                };
                //获得消息事件
                socket.onmessage = function(msg) {
                    var serverMsg = "收到服务端信息:" + msg.data;
                    console.log(serverMsg);
                    //发现消息进入    开始处理前端触发逻辑
                };
                //关闭事件
                socket.onclose = function() {
                    console.log("websocket已关闭");
                };
                //发生了错误事件
                socket.onerror = function() {
                    console.log("websocket发生了错误");
                }
            }
        }
        function sendMessage() {
            if(typeof(WebSocket) == "undefined") {
                console.log("您的浏览器不支持WebSocket");
            }else {
                // console.log("您的浏览器支持WebSocket");
                var toUserId = document.getElementById('toUserId').value;
                var contentText = document.getElementById('contentText').value;
                var msg = '{"toUserId":"'+toUserId+'","contentText":"'+contentText+'"}';
                console.log(msg);
                socket.send(msg);
            }
        }
    
        </script>
    </html>
    

    源码地址

    参考链接:https://www.cnblogs.com/JohanChan/p/12522001.html
    https://www.kancloud.cn/hanxt/springboot2/1185843

    I can feel you forgetting me。。 有一种默契叫做我不理你,你就不理我

  • 相关阅读:
    PHP isset()和empty()区别
    C++ 需要注意的知识点
    Unreal Engine:Socket源码解析
    Unreal Engine:动态内存和智能指针
    K8S 如何重启 Pod
    如何使用 nginx 对后端服务做主备
    K8S 集群安装 metalLB 使用 EIP
    Centos 7 系统安装后初始化操作
    K8S v1.20 及以上版本 StorageClass 创建 PVC 不成功解决
    K8S 如何查看 pod 中的容器
  • 原文地址:https://www.cnblogs.com/weidaijie/p/14419635.html
Copyright © 2020-2023  润新知