zoukankan      html  css  js  c++  java
  • springboot使用websocket

    Springboot 集成 websocket

    1.介绍

    WebSocket是HTML5新增的协议,它的目的是在浏览器和服务器之间建立一个不受限的双向通信的通道。实时推送数据/通知到浏览器

    方法一

    1、引入WebSocket依赖包

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

    2、编写 WebSocket 实现方法

     @ServerEndpoint(value = "/websocket/{id}")
        @Component
        public class WebSocketServer {
        
            /**
             * 静态常量,记录连接个数,线程安全
             */
            private static int onlineCount = 0;
        
            /**
             * 存放客户端对应的WebSocket对象
             */
            private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();
        
            /**
             * 会话信息
             */
            private Session session;
        
            @OnOpen
            public void onOpen(Session session){
                this.session = session;
                webSocketSet.add(this);
                addOnlineCount();
                try {
                    sendMessage("连接成功");
                }catch (IOException ex){
                    System.out.println(ex.getMessage());
                }
            }
        
            @OnMessage
            public void onMessage(String message, Session session, @PathParam("id")String id){
                System.out.println("来自客户端的消息:" + message);
        
                //群发消息
                for (WebSocketServer item : webSocketSet) {
                    try {
                        item.sendMessage(message);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        
            @OnClose
            public void onClass(){
                webSocketSet.remove(this);
                subOnlineCount();
                System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
            }
        
            @OnError
            public void onError(Session session,Exception ex){
                ex.printStackTrace();
            }
        
            /**
             * 发送消息
             * @param message
             * @throws IOException
             */
            private void sendMessage(String message) throws IOException {
                this.session.getBasicRemote().sendText(message);
            }
            
            private void sendInfo(String message){
                System.out.println(message );
                for (WebSocketServer item:webSocketSet ) {
        
                    try{
                        item.sendMessage(message);
                    }catch (IOException ex){
                        System.out.println(ex.getMessage());
        
                    }
                }
            }
        
            private synchronized void addOnlineCount(){
                WebSocketServer.onlineCount ++;
            }
        
            private synchronized void subOnlineCount(){
                WebSocketServer.onlineCount --;
            }
        
            public static synchronized long getOnlineCount(){
                return WebSocketServer.onlineCount;
            }
        }
        
    

    3、 添加配置文件

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

    方法二

    1. 编写消息处理类
    public class WebSocketMessageHandler extends TextWebSocketHandler {
    
        /**
         * 静态常量,保存连接数量,线程安全
         */
        private static long onlineCount = 0;
    
        /**
         * 保存客户端信息
         */
        private static CopyOnWriteArraySet<WebSocketSession> webSocketSet = new CopyOnWriteArraySet();
    
        /**
         * 会话信息
         */
        private WebSocketSession session;
    
        public WebSocketMessageHandler(){
            super();
        }
    
        /**
         * 连接建立之后
         * @param session
         * @throws Exception
         */
        public void afterConnectionEstablished(WebSocketSession session) throws Exception{
            this.session = session;
            webSocketSet.add(session);
            addOnlineCount();
            System.out.println("连接成功,当前连接数:"+getOnlineCount());
        }
    
        /**
         * 处理收到的websocket信息
         */
        @Override
        protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
            String payload = message.getPayload();
            System.out.println("sadddddd");
            sendMessage(payload);
        }
    
        public void handleTransportError(WebSocketSession session, Throwable var2) throws Exception{
    
        }
    
        public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception{
           webSocketSet.remove(session);
            subOnlineCount();
            System.out.println("连接断开,当前连接数:"+getOnlineCount());
    
        }
    
        private void sendMessage(String message)  throws IOException {
            for (WebSocketSession session: webSocketSet ) {
                session.sendMessage(new TextMessage( message));
            }
        }
    
        ///////
        private synchronized void addOnlineCount(){
    
            onlineCount++;
        }
        private synchronized void subOnlineCount(){
    
            onlineCount--;
        }
        private synchronized long  getOnlineCount(){
    
            return this.onlineCount;
        }
    }
    

    2、位置文件

    
    @Configuration
    public class WebSocketConfig implements WebSocketConfigurer {
    
        @Override
        public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
            webSocketHandlerRegistry.addHandler(handler(),"/notice/{id}")//访问地址
            .setAllowedOrigins("*");///解决跨域问题
        }
    
        public WebSocketHandler handler(){
            return  new WebSocketMessageHandler();
        }
    }
    

    总结

    1、网上找资料按照第一种实现,结果总是报错,比较靠谱的解释是aop拦截问题,使得ServerEndpointExporter
    注册不进去;

    2、第二种方法有效,一定不要忘记加依赖文件

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

    测试页面

    <!DOCTYPE HTML>
    <html>
       <head>
       <meta charset="">
       <title>WebSocket</title>
        
          <script type="text/javascript">
    	   var ws = null;
             function WebSocketTest()
             {
                if ("WebSocket" in window)
                {
                   console.log("您的浏览器支持 WebSocket!");
                   
    			   if(ws == null)
                   // 打开一个 web socket
    				ws = new WebSocket("ws://localhost:8001/voice/aass");
                    
                   ws.onopen = function()
                   {
                      // Web Socket 已连接上,使用 send() 方法发送数据
                      ws.send("00000000000000000000000");
                      console.log("数据发送中...");
                   };
                    
                   ws.onmessage = function (evt) 
                   { 
    				   
                      var received_msg = evt.data;
    				  
                      console.log("数据已接收...");
    				  console.log(received_msg);
    
                   };
                    
                   ws.onclose = function()
                   { 
                      // 关闭 websocket
                      console.log("连接已关闭...");
    				 closeWS();
                   };
                }
                
                else
                {
                   // 浏览器不支持 WebSocket
                   console.log("您的浏览器不支持 WebSocket!");
                }
             }
    		 function closeWS(){
    			if(ws !=null){
    				ws.close();
    				ws = null;
    			}
    		 }
    
    		 function sendMsg(){
    			 ws.send("00000000000000000000000");
                 console.log("数据发送中...");
    		 }
          </script>
            
       </head>
       <body>
       
          <div id="sse">
             <a href="javascript:WebSocketTest()">运行 WebSocket</a>
    		  <a href="javascript:closeWS()">关闭 WebSocket</a>
    		  <br/>
    		<a href="javascript:sendMsg()">发送消息</a>
    
          </div>
          
       </body>
    </html>
    
  • 相关阅读:
    进程之管道Pipe,数据共享Manager,进程池Poo
    进程之锁,信息量,事件,队列,生产者消费者模型,joinablequeue
    网络编程之sock server,自定义一个与sock server类相似的功能,支持多客户端通信
    网络编程之粘包解决方案
    进程之进程创建的两种方式,两种传值的方式,验证进程间数据隔离,join,守护进程,僵尸进程,孤儿进程
    毕业设计开题报告任务书参考文献格式和数量要求
    剑指offer-替换空格
    剑指offer-二维数组中的查找
    用forward和sendRedirect转发时的区别
    ServletContext实现显示用户在线人数
  • 原文地址:https://www.cnblogs.com/monkay/p/11170262.html
Copyright © 2011-2022 走看看