• 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;
     }
    }
    
    1. 位置文件
    
    @Configuration
    public class WebSocketConfig implements WebSocketConfigurer {
    
        @Override
        public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
            webSocketHandlerRegistry.addHandler(handler(),"/notice/{id}")//访问地址
            .setAllowedOrigins("*");///解决跨域问题
        }
    
        public WebSocketHandler handler(){
            return  new WebSocketMessageHandler();
        }
    }
    

    测试页面

    <!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>
    

    总结

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

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

    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
       </dependency>
    
  • 相关阅读:
    mysql那些事(1)手机号与座机号码如何存储
    分享一个PHP调用RestFul接口的函数
    php sprintf用法
    HTTP状态码详解
    PHP随机生成中国人姓名的类
    PHP计算两组经纬度坐标之间的距离
    PHP根据经纬度获取在范围坐标的数据
    PHP 利用QQ邮箱发送邮件「PHPMailer」
    PHP中利用PHPMailer配合QQ邮箱实现发邮件
    修改PHP上传文件大小限制
  • 原文地址:https://www.cnblogs.com/monkay/p/11130255.html
Copyright © 2020-2023  润新知