springboot整合websocket實現群聊思路代碼詳解

實現思路

image-20210528112407993

發送者向服務器發送大傢早上好。其它客戶端可以收到對應消息。

項目展示

image-20210528111445032

通過springboot引入websocket,實現群聊,通過在線websocket測試進行展示。

核心代碼

pom引入jar

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.10.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>
    </dependencies>

使用springboot 2.3.10.RELEASE版本;java8

WebSocketConfig配置類

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

websocket有4個註解,解釋如下

  • @OnOpen 有新連接
  • @OnMessage 有新消息時
  • @OnClose 關閉連接
  • @OnError 連接異常

對於這個4個註解,配置在方法上即可。

WebsocketServerEndpoint接收類

@Slf4j
@Controller
@ServerEndpoint ("/")
public class WebsocketServerEndpoint
{
   @OnOpen
   public void onOpen(Session session, EndpointConfig config) {
      log.info("[onOpen][session({}) 接入]", session);
      WebSocketUtil.broadcast (session.getId ()+"上線瞭");
      WebSocketUtil.addSession (session);
   }
   @OnMessage
   public void onMessage(Session session, String message) {
      WebSocketUtil.broadcast (message);
      log.info("[onOpen][session({}) 接收到一條消息({})]", session, message); // 生產環境下,請設置成 debug 級別
   }
   @OnClose
   public void onClose(Session session, CloseReason closeReason) {
      WebSocketUtil.removeSession (session);
      WebSocketUtil.broadcast (session.getId ()+"下線瞭");
      log.info("[onClose][session({}) 連接關閉。關閉原因是({})}]", session, closeReason);
   }
   @OnError
   public void onError(Session session, Throwable throwable) {
      log.info("[onClose][session({}) 發生異常]", session, throwable);
   }
}

WebSocketUtil工具類

@Slf4j
public class WebSocketUtil
{


    // ========== 會話相關 ==========

    /**
     * Session 與用戶的映射
     */
    private static final Map<String, Session> SESSION_USER_MAP = new ConcurrentHashMap<> ();

    /**
     * 添加 Session 。在這個方法中,會添加用戶和 Session 之間的映射
     *
     * @param session Session
     */
    public static void addSession(Session session) {
        // 更新 SESSION_USER_MAP
        SESSION_USER_MAP.put(session.getId (), session);
    }

    /**
     * 移除 Session 。
     *
     * @param session Session
     */
    public static void removeSession(Session session) {
        // 從 SESSION_USER_MAP 中移除
          SESSION_USER_MAP.remove(session.getId ());

    }

    // ========== 消息相關 ==========

    /**
     * 廣播發送消息給所有在線用戶
     *
     * @param message 消息體
     * @param <T> 消息類型
     */
    public static <T extends Message> void broadcast(String message) {
        // 創建消息
//        String messageText = buildTextMessage(type, message);
        // 遍歷 SESSION_USER_MAP ,進行逐個發送
        for (String sessionId : SESSION_USER_MAP.keySet()) {
            sendTextMessage(SESSION_USER_MAP.get (sessionId), message);
        }
    }

    /**
     * 發送消息給單個用戶的 Session
     *
     * @param session Session
     * @param type 消息類型
     * @param message 消息體
     * @param <T> 消息類型
     */
    public static <T extends Message> void send(Session session, String type, T message) {
        // 創建消息
        String messageText = buildTextMessage(type, message);
        // 遍歷給單個 Session ,進行逐個發送
        sendTextMessage(session, messageText);
    }


    /**
     * 構建完整的消息
     *
     * @param type 消息類型
     * @param message 消息體
     * @param <T> 消息類型
     * @return 消息
     */
    private static <T extends Message> String buildTextMessage(String type, T message) {
        JSONObject messageObject = new JSONObject();
        messageObject.put("type", type);
        messageObject.put("body", message);
        return messageObject.toString();
    }

    /**
     * 真正發送消息
     *
     * @param session Session
     * @param messageText 消息
     */
    private static void sendTextMessage(Session session, String messageText) {
        if (session == null) {
            log.error("[sendTextMessage][session 為 null]");
            return;
        }
        RemoteEndpoint.Basic basic = session.getBasicRemote();
        if (basic == null) {
            log.error("[sendTextMessage][session 的  為 null]");
            return;
        }
        try {
            basic.sendText(messageText);
        } catch (IOException e) {
            log.error("[sendTextMessage][session({}) 發送消息{}) 發生異常",
                    session, messageText, e);
        }
    }

}

在線websocket調試輸入ws://localhost:8080/即可。

以上就是springboot整合websocket實現群聊思路代碼詳解的詳細內容,更多關於springboot整合websocket的資料請關註WalkonNet其它相關文章!

推薦閱讀: