springboot websocket 知识点汇总

07-19 1070阅读

以下是一个详细全面的 Spring Boot 使用 WebSocket 的知识点汇总

1. 配置 WebSocket

添加依赖

进入maven官网, 搜索spring-boot-starter-websocket,选择版本, 然后把依赖复制到pom.xml的dependencies标签中

springboot websocket 知识点汇总

配置 WebSocket

创建一个配置类 WebSocketConfig,并启用 WebSocket 支持:

这个类的主要作用就是

  • 启用 WebSocket 支持: 这个配置类通过返回 ServerEndpointExporter 实例来启用 WebSocket 支持。
  • 自动注册端点: 它会自动注册用 @ServerEndpoint 注解标识的 WebSocket 端点,使它们能够处理 WebSocket 请求。
    package com.example.websocketdemo.config;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.socket.server.standard.ServerEndpointExporter;
    @Configuration
    public class WebSocketConfig {
        
        @Bean
        public ServerEndpointExporter serverEndpointExporter() {
            return new ServerEndpointExporter();
        }
    }
    

    2. 创建 WebSocket 端点

    创建一个 WebSocket 端点 WebSocketServer,处理客户端与服务器之间的 WebSocket 通信。

    当一个用户向服务端发送socket连接时, 相当于创建了一个WebSocketServer 类的实例对象

    代码中的Session 放到文章最后讲。

    package com.example.websocketdemo.websocket;
    import jakarta.websocket.*;
    import jakarta.websocket.server.PathParam;
    import jakarta.websocket.server.ServerEndpoint;
    import org.springframework.stereotype.Component;
    @Component	// 下面路径最后面不要写 '/'这个符号
    @ServerEndpoint("/websocket/{username}")	// 我们配置的有WebSocketConfig类, 所以可以使用这个注解
    public class WebSocketServer {
        private Session session;
        @OnOpen	// 建立连接的时候会调用这个函数
        public void onOpen(Session session, @PathParam("username") String username) {
            this.session = session;
            System.out.println("Connected with username: " + username);
        }
        @OnMessage	// 接收到客户端的信息时调用
        public void onMessage(String message, Session session) {
            System.out.println("Received message: " + message);
            try {
                session.getBasicRemote().sendText("Server received [" + message + "]");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        @OnClose	// 关闭连接的时候调用
        public void onClose(Session session) {
            System.out.println("Session closed");
        }
        @OnError	// 错误时调用
        public void onError(Session session, Throwable throwable) {
            throwable.printStackTrace();
        }
    }
    

    3. Spring Security 配置(可选)

    如果你的应用使用了 Spring Security,可能需要配置忽略 WebSocket 端点的安全检查:

    需要在你的SecurityConfig 类中添加下面内容才可以让服务器接收到websocket的请求。SecurityConfig是一个管理Spring Security的自定义类

    package com.example.websocketdemo.config;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.web.builders.WebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
    @Configuration
    public class SecurityConfig {
        @Bean
        public WebSecurityCustomizer webSecurityCustomizer() {
            return (web) -> web.ignoring().requestMatchers("/websocket/**");
        }
    }
    

    4. 客户端代码

    可以使用 JavaScript 在前端与 WebSocket 服务器进行通信。

        let socket = null;
        function connect() {
            let username = "your user name";
            
            // @ServerEndpoint("/websocket/{username}")	这里也可以传递其他参数, 比如token, 它会被服务端的这个注解接收到
            socket = new WebSocket('ws://localhost:8080/websocket/' + username);
    		
    		// 建立连接时会调用
            socket.onopen = function(event) {
                
            };
    		// 接收到服务端的信息时调用
            socket.onmessage = function(event) {
                
            };
    		
    		// 关闭连接时调用
            socket.onclose = function(event) {
                
            };
    		
    		// 错误时调用
            socket.onerror = function(event) {
                
            };
    		
    		// 也可以通过close()手动关闭连接, 他会调用onclose(), 一般vue中在取消挂在组件时手动关闭连接
    		socket.close(); 
    		
    		// 向服务端发送信息, message最好是json格式, JSON.stringify()
    		socket.send(message)
        }
    
    

    5. 处理 JSON 消息

    在信息交换的时候, 我们一般用JSON格式的信息。Java 标准库中并不包含直接处理 JSON 的功能。因此,需要引入第三方库来处理 JSON 数据。

    这里我们讲的是 Alibaba 提供的 fastjson, 还是在 maven官网 搜索 fastjson 选择对应版本, 引入到pom.xml的dependencies标签中。

    // 将 Java 对象序列化为 JSON 字符串
    String jsonString = JSON.toJSONString(user);
            
    // 将 JSON 字符串反序列化为 Java 对象
    User deserializedUser = JSON.parseObject(jsonString, User.class);
    // 创建一个 JSONObject
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("name", "John");
    // 转换成JSON字符串
    jsonObject.toString()
    // 解析 JSON 字符串
    String jsonString = "{\"name\":\"ld\",\"age\":18,\"city\":\"ShangHai\"}";
    JSONObject parsedObject = JSONObject.parseObject(jsonString);
    // 获取value, 输出 ld
    System.out.println("Name: " + parsedObject.getString("name"));
    

    6. Session

    Session 在 WebSocket 中是一个重要的概念,它代表了客户端和服务器之间的 WebSocket 连接。通过 Session 对象,你可以发送和接收消息、获取连接信息、管理连接状态以及处理连接中的错误。

    1. 创建 WebSocket 服务器端点

    在 Java 中使用 WebSocket 的第一步是创建一个 WebSocket 服务器端点。通过使用 @ServerEndpoint 注解,你可以定义 WebSocket 服务器端点,并处理连接、关闭、消息和错误事件。

    示例代码:

    import jakarta.websocket.OnClose;
    import jakarta.websocket.OnError;
    import jakarta.websocket.OnMessage;
    import jakarta.websocket.OnOpen;
    import jakarta.websocket.Session;
    import jakarta.websocket.server.ServerEndpoint;
    import java.io.IOException;
    @ServerEndpoint("/websocket")
    public class WebSocketServer {
        
        @OnOpen
        public void onOpen(Session session) {
            System.out.println("Connected: " + session.getId());
        }
        @OnMessage
        public void onMessage(String message, Session session) throws IOException {
            System.out.println("Received: " + message);
            session.getBasicRemote().sendText("Echo: " + message);
        }
        @OnClose
        public void onClose(Session session) {
            System.out.println("Disconnected: " + session.getId());
        }
        @OnError
        public void onError(Session session, Throwable throwable) {
            throwable.printStackTrace();
        }
    }
    
    2. Session 对象的常用方法
    • 获取连接的唯一 ID:session.getId()
    • 发送消息:
      • 发送文本消息:session.getBasicRemote().sendText("message")
      • 发送二进制消息:session.getBasicRemote().sendBinary(ByteBuffer buffer)
      • 获取连接的基本信息:
        • 获取连接的 URI:session.getRequestURI()
        • 获取连接的参数:session.getPathParameters()
        • 获取连接的请求参数:session.getRequestParameterMap()
        • 关闭连接:session.close()
        • 检查连接状态:session.isOpen()
          3. 处理消息

          在 WebSocket 中,处理消息是通过 @OnMessage 注解的方法实现的。你可以在这个方法中处理来自客户端的消息,并使用 Session 对象发送响应。

          示例代码:

          @OnMessage
          public void onMessage(String message, Session session) throws IOException {
              System.out.println("Received: " + message);
              // 向客户端发送回显消息
              session.getBasicRemote().sendText("Echo: " + message);
          }
          
          4. 处理连接和断开

          @OnOpen 和 @OnClose 注解的方法分别用于处理连接建立和连接断开事件。在这些方法中,你可以执行一些初始化或清理操作。

          示例代码:

          @OnOpen
          public void onOpen(Session session) {
              System.out.println("Connected: " + session.getId());
          }
          @OnClose
          public void onClose(Session session) {
              System.out.println("Disconnected: " + session.getId());
          }
          
          5. 处理错误

          @OnError 注解的方法用于处理 WebSocket 连接中的错误。在这个方法中,你可以记录错误信息或执行其他的错误处理操作。

          示例代码:

          @OnError
          public void onError(Session session, Throwable throwable) {
              throwable.printStackTrace();
          }
          

          6. 使用 Session 进行高级操作

          6.1 保存和共享用户状态

          在 WebSocket 应用中,你可以使用 Session 对象来保存和共享用户状态。例如,你可以在 Session 对象中存储用户的身份信息,并在后续的消息处理中使用这些信息。

          示例代码:

          @OnOpen
          public void onOpen(Session session) {
              session.getUserProperties().put("username", "John");
          }
          @OnMessage
          public void onMessage(String message, Session session) throws IOException {
              String username = (String) session.getUserProperties().get("username");
              session.getBasicRemote().sendText("Hello, " + username + "! You sent: " + message);
          }
          
          6.2 广播消息

          你可以使用 Session 对象的集合来实现消息的广播,即将消息发送给所有连接的客户端。

          示例代码:

          import java.util.Collections;
          import java.util.HashSet;
          import java.util.Set;
          @ServerEndpoint("/websocket")
          public class WebSocketServer {
              private static Set sessions = Collections.synchronizedSet(new HashSet());
              @OnOpen
              public void onOpen(Session session) {
                  sessions.add(session);
                  System.out.println("Connected: " + session.getId());
              }
              @OnClose
              public void onClose(Session session) {
                  sessions.remove(session);
                  System.out.println("Disconnected: " + session.getId());
              }
              @OnMessage
              public void onMessage(String message, Session session) throws IOException {
                  for (Session s : sessions) {
                      if (s.isOpen()) {
                          s.getBasicRemote().sendText("Broadcast: " + message);
                      }
                  }
              }
              @OnError
              public void onError(Session session, Throwable throwable) {
                  throwable.printStackTrace();
              }
          }
          

          文章到这里就这束了!~

          其他文章地址:

          快速入门,springboot知识点汇总

          springboot常用注解大全(超详细, 30个)

          springboot websocket知识点汇总

          spring cloud知识点汇总, 待更

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]