SpringBoot集成WebSocket實現(xiàn)雙屏實時消息互推功能
前言
在項目開發(fā)中,實時消息推送是高頻需求,比如雙屏聯(lián)動、大屏監(jiān)控、在線聊天、訂單狀態(tài)推送等場景。WebSocket 作為 HTML5 的核心特性,實現(xiàn)了瀏覽器與服務器的全雙工雙向通信,相比傳統(tǒng)的輪詢 / 長輪詢方式,大幅降低服務端壓力,提升實時性和用戶體驗。
本文以SpringBoot 2.7.x(最穩(wěn)定版本,零基礎友好)為基礎,手把手教大家從 0 到 1 集成 WebSocket,實現(xiàn)左屏 / 右屏雙端實時消息互推功能。全程代碼可直接復制使用,兼顧Jar 包內嵌 Tomcat和War 包外部 Tomcat兩種部署方式,解決部署沖突問題,同時完善異常處理、連接管理、心跳檢測等生產級細節(jié),小白跟著步驟走就能跑通。
本文核心優(yōu)勢
- 零基礎友好:代碼全復制、步驟全拆解,無復雜配置,新手直接用;
- 部署無坑:自動適配 Jar/War 包部署,無需手動修改代碼,避免容器沖突;
- 生產級健壯:完善的異常處理、失效連接清理、心跳檢測,防止內存泄漏;
- 支持多端登錄:同一用戶多設備連接,所有端都能收到消息,避免 Session 覆蓋;
- 雙測試方式:在線工具快速驗證 + 自定義 HTML 頁面,前端后端全打通;
- 配套全補全:統(tǒng)一響應類、啟動類改造等缺失代碼全部補全,無需額外找依賴。
一、環(huán)境準備(新手必看)
1.1 基礎開發(fā)環(huán)境
無需高版本,基礎環(huán)境即可運行,推薦搭配:
- JDK:1.8(兼容性最好,無版本問題)
- SpringBoot:2.7.10(本文統(tǒng)一版本,避免依賴沖突)
- Maven:3.6.0+
- 開發(fā)工具:IDEA/Eclipse(推薦 IDEA,自帶 Maven 管理)
- 測試工具:瀏覽器、WebSocket 在線測試工具
1.2 核心依賴
在pom.xml中引入 SpringBoot 官方的 WebSocket Starter 依賴,無需額外引入其他包,Spring 已做封裝:
<!-- SpringBoot集成WebSocket核心依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!-- 可選:SpringMVC基礎依賴(項目已引入可忽略) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
二、核心配置類(解決 Jar/War 部署兼容)
SpringBoot 中使用@ServerEndpoint注解實現(xiàn) WebSocket 時,必須注冊ServerEndpointExporter 讓 Spring 掃描并管理 WebSocket 端點,但內嵌 Tomcat(Jar 包)和外部 Tomcat(War 包) 對該 Bean 的要求不同:
Jar 包部署(內嵌 Tomcat):需要手動創(chuàng)建ServerEndpointExporter Bean;
War 包部署(外部 Tomcat):由容器自身初始化 WebSocket,手動創(chuàng)建會導致 Bean 沖突。
因此我們通過Spring 條件注解@Conditional 實現(xiàn)動態(tài)判斷,自動適配兩種部署方式。
- Jar 包部署(內嵌 Tomcat):需要手動創(chuàng)建ServerEndpointExporter Bean;
- War 包部署(外部 Tomcat):由容器自身初始化 WebSocket,手動創(chuàng)建會導致 Bean 沖突。
2.1 自定義條件判斷類
創(chuàng)建包com.tydt.framework.config,編寫WebSocketAutoWired類,實現(xiàn)Condition接口,核心邏輯是判斷是否為內嵌 Tomcat 環(huán)境:
/**
* All rights reserved.
*/
package com.itl.framework.config;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.util.ClassUtils;
/**
* 類描述:WebSocket條件判斷類,控制ServerEndpointExporter是否創(chuàng)建
* jar包部署(內嵌Tomcat)返回true,war包部署(外部Tomcat)返回false
* @author itl
* @version 1.0
*
* 修訂歷史:
* 日期 修訂者 修訂描述
* 2026-02-05 xxx 修復matches方法固定返回false問題,實現(xiàn)jar/war包部署動態(tài)判斷
*/
public class WebSocketAutoWired implements Condition {
/**
* 核心判斷方法:jar包部署(內嵌Tomcat)為true; war包部署(外部Tomcat)為false
*/
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 判斷類加載器中是否存在內嵌Tomcat核心類 → 存在=jar包部署,不存在=war包部署
return ClassUtils.isPresent(
"org.apache.catalina.startup.Tomcat",
context.getClassLoader()
);
}
}
2.2 WebSocket 核心配置類
編寫WebSocketConfig類,通過@Conditional關聯(lián)上面的條件判斷類,動態(tài)創(chuàng)建ServerEndpointExporter:
/**
*
* All rights reserved.
*/
package com.itl.framework.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* 類描述:WebSocket核心配置類
* 動態(tài)創(chuàng)建ServerEndpointExporter,解決內嵌Tomcat/外部Tomcat部署兼容問題
* @author itl
* @version 1.0
* 新增條件注解,適配內嵌/外部Tomcat
*/
@Configuration
public class WebSocketConfig {
/**
* 注冊WebSocket端點處理器,僅內嵌Tomcat(jar包)時創(chuàng)建
* 外部Tomcat(war包)由容器自身初始化,無需手動創(chuàng)建
*/
@Bean
@Conditional(WebSocketAutoWired.class)
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
核心原理:項目啟動時,Spring 會根據(jù)WebSocketAutoWired的matches方法返回值,動態(tài)決定是否創(chuàng)建ServerEndpointExporter Bean,從根本上解決 Jar/War 部署的沖突問題。
三、WebSocket 工具類(連接管理 + 消息發(fā)送)
創(chuàng)建工具類WebSocketUtils,用于統(tǒng)一管理客戶端 Session 連接、發(fā)送消息、移除連接等操作,使用ConcurrentHashMap保證多線程下的線程安全,同時支持同一用戶多端連接(避免 Session 被覆蓋)。
包路徑:com.itl.common.utils
/**
* All rights reserved.
*/
package com.itl.common.utils;
import java.util.Map;
import java.util.Set;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import javax.websocket.Session;
/**
* 類描述:WebSocket工具類,管理客戶端Session和消息發(fā)送
* @author itl
*
* 修訂歷史:
* 日期 修訂者 修訂描述
* 優(yōu)化Session管理,支持單用戶多連接;增加異常處理和Session有效性判斷
*/
public class WebSocketUtils {
// 存儲客戶端連接:key=用戶ID,value=該用戶的所有Session連接(支持多端登錄)
public static Map<String, Set<Session>> clients = new ConcurrentHashMap<>();
/**
* 添加客戶端連接
* @param userId 用戶唯一標識
* @param session 客戶端會話
*/
public static void add(String userId, Session session) {
// 不存在則創(chuàng)建新的Set,存在則直接添加;ConcurrentHashMap.newKeySet()保證線程安全
clients.computeIfAbsent(userId, k -> ConcurrentHashMap.newKeySet()).add(session);
}
/**
* 處理客戶端發(fā)送的消息(可根據(jù)業(yè)務自定義)
* @param userId 發(fā)送消息的用戶ID
* @param message 消息內容
*/
public static void receive(String userId, String message) {
// 示例:雙屏聯(lián)動,左屏消息推右屏,右屏消息推左屏
if ("left".equals(userId)) {
sendMessage("right", "左屏推送:" + message);
} else if ("right".equals(userId)) {
sendMessage("left", "右屏推送:" + message);
}
System.out.println("收到用戶[" + userId + "]的消息:" + message);
}
/**
* 精準移除某用戶的某一個Session連接(連接關閉/異常時調用)
* @param userId 用戶唯一標識
* @param session 要移除的會話
*/
public static void remove(String userId, Session session) {
Set<Session> sessions = clients.get(userId);
if (sessions != null) {
sessions.remove(session);
// 若該用戶無任何連接,移除key,避免空集合占用內存
if (sessions.isEmpty()) {
clients.remove(userId);
}
}
}
/**
* 移除某用戶的所有連接
* @param userId 用戶唯一標識
*/
public static void remove(String userId) {
clients.remove(userId);
}
/**
* 向指定用戶發(fā)送消息
* @param userId 接收消息的用戶ID
* @param message 消息內容
* @return 成功發(fā)送的連接數(shù)
*/
public static int sendMessage(String userId, String message) {
Set<Session> sessions = clients.get(userId);
// 無該用戶連接,直接返回0
if (sessions == null || sessions.isEmpty()) {
return 0;
}
int successCount = 0;
Iterator<Session> it = sessions.iterator();
while (it.hasNext()) {
Session session = it.next();
// 判斷Session是否有效(連接未關閉)
if (!session.isOpen()) {
it.remove(); // 移除失效Session,避免內存泄漏
continue;
}
try {
// 異步發(fā)送消息(推薦),同步發(fā)送使用session.getBasicRemote().sendText(message)
session.getAsyncRemote().sendText(message);
successCount++;
} catch (Exception e) {
it.remove(); // 發(fā)送失敗,移除失效Session
e.printStackTrace(); // 實際項目建議使用日志框架(如Logback/Log4j2)
}
}
// 清理空集合
if (sessions.isEmpty()) {
clients.remove(userId);
}
return successCount;
}
}
關鍵優(yōu)化點:
- 把原有的Map<String, Session>改為Map<String, Set>,支持同一用戶多端登錄,所有連接都能收到消息;
- 增加Session有效性判斷(session.isOpen()),避免向失效連接發(fā)送消息;
- 完善的異常捕獲,發(fā)送消息失敗時自動移除失效 Session,防止內存泄漏;
- 提供精準移除(單 Session)和批量移除(全 Session)兩種方法,適配不同場景。
四、WebSocket 服務端端點(核心業(yè)務處理)
創(chuàng)建WebSocketService類,使用@ServerEndpoint注解定義 WebSocket 服務端地址,通過@OnOpen、@OnMessage、@OnClose、@OnError注解處理 WebSocket 的連接打開、接收消息、連接關閉、連接異常四大事件,同時通過@Component注解讓 Spring 管理該 Bean。
包路徑:com.itl.framework.web.service
/**
* All rights reserved.
*/
package com.itl.framework.web.service;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import org.springframework.stereotype.Component;
import com.itl.common.utils.WebSocketUtils;
/**
* 類描述:WebSocket服務端端點,處理客戶端連接和事件回調
* 服務端地址:/connect/{userId}
* @author itl
* 修復onError方法參數(shù)注解問題;優(yōu)化連接管理,精準移除Session
*/
@ServerEndpoint("/connect/{userId}") // WebSocket連接地址,{userId}為用戶唯一標識
@Component // 必須交給Spring管理,否則無法掃描
public class WebSocketService {
/**
* 連接打開事件(客戶端首次連接時調用)
* @param userId 路徑參數(shù)中的用戶ID
* @param session 客戶端會話
*/
@OnOpen
public void onOpen(@PathParam("userId") String userId, Session session) {
System.out.println("【WebSocket】連接打開成功!");
WebSocketUtils.add(userId, session);
System.out.println("【WebSocket】用戶" + userId + "上線,當前在線人數(shù):" + WebSocketUtils.clients.size());
}
/**
* 接收客戶端消息事件
* @param userId 發(fā)送消息的用戶ID
* @param message 客戶端發(fā)送的消息
* @return 服務端向客戶端的回執(zhí)消息
*/
@OnMessage
public String onMessage(@PathParam("userId") String userId, String message) {
// 心跳檢測(可選),客戶端發(fā)送&時,服務端回執(zhí)&,避免連接被斷開
if (message.equals("&")) {
return "&";
} else {
// 調用工具類處理消息
WebSocketUtils.receive(userId, message);
return "【服務端回執(zhí)】已收到消息:" + message;
}
}
/**
* 連接異常事件(網絡中斷、客戶端崩潰等)
* 注意:@OnError注解不支持@PathParam參數(shù),會導致參數(shù)解析異常
* @param session 異常的客戶端會話
* @param throwable 異常信息
*/
@OnError
public void onError(Session session, Throwable throwable) {
// 遍歷移除該失效的Session
WebSocketUtils.clients.forEach((userId, sessions) -> {
WebSocketUtils.remove(userId, session);
});
throwable.printStackTrace();
System.out.println("【WebSocket】連接異常,已移除失效會話");
}
/**
* 連接關閉事件(客戶端主動關閉連接)
* @param userId 斷開連接的用戶ID
* @param session 關閉的客戶端會話
*/
@OnClose
public void onClose(@PathParam("userId") String userId, Session session) {
System.out.println("【WebSocket】連接關閉成功!");
WebSocketUtils.remove(userId, session);
System.out.println("【WebSocket】用戶" + userId + "下線,當前在線人數(shù):" + WebSocketUtils.clients.size());
}
}
核心注意點:
- @ServerEndpoint(“/connect/{userId}”):定義 WebSocket 的服務端連接地址,前端通過ws://ip:port/connect/left連接左屏,ws://ip:port/connect/right連接右屏;
- @Component:必須添加,否則 Spring 無法掃描到該端點,配合配置類的ServerEndpointExporter完成注冊;
- @OnError方法不支持@PathParam注解:原代碼中該注解會導致運行時參數(shù)解析異常,直接通過 Session 遍歷移除即可;
- 增加心跳檢測:客戶端定時發(fā)送&,服務端回執(zhí)&,避免因長時間無交互導致連接被防火墻 / 服務器斷開。
五、測試接口(HTTP 觸發(fā) WebSocket 消息推送)
創(chuàng)建 Controller,提供 HTTP 接口,用于通過后端接口觸發(fā) WebSocket 消息推送(比如業(yè)務系統(tǒng)調用接口向前端推送消息),實現(xiàn)左屏 / 右屏雙端消息互推,同時使用AjaxResult返回統(tǒng)一的響應結果(SpringBoot 項目通用)。
import com.itl.common.utils.WebSocketUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* WebSocket測試控制器,雙屏消息互推接口
* @author itl
* @date 2026-02-05
*/
@RestController
@RequestMapping("/websocket")
@Api(tags = "WebSocket測試接口")
public class WebSocketController {
/**
* 接收左屏消息并推送至右屏
* @param message 消息內容
* @return 推送結果(1=成功,0=失?。?
*/
@ApiOperation(value = "左屏推右屏", notes = "HTTP接口觸發(fā),向右屏推送消息")
@ApiImplicitParam(name = "message", value = "推送的消息內容", required = true, dataType = "String")
@GetMapping(value = "/right")
public AjaxResult right(String message) {
// toAjax:通用工具類,1=成功,0=失敗
return toAjax(WebSocketUtils.sendMessage("right", message));
}
/**
* 接收右屏消息并推送至左屏
* @param message 消息內容
* @return 推送結果(1=成功,0=失?。?
*/
@ApiOperation(value = "右屏推左屏", notes = "HTTP接口觸發(fā),向左屏推送消息")
@ApiImplicitParam(name = "message", value = "推送的消息內容", required = true, dataType = "String")
@GetMapping(value = "/left")
public AjaxResult left(String message) {
return toAjax(WebSocketUtils.sendMessage("left", message));
}
/**
* 通用響應結果封裝(項目已實現(xiàn)可忽略)
* @param rows 成功數(shù)
* @return AjaxResult
*/
private AjaxResult toAjax(int rows) {
return rows > 0 ? AjaxResult.success() : AjaxResult.error();
}
}
接口說明:
- 左屏推右屏:GET http://ip:port/websocket/right?message=測試消息
- 右屏推左屏:GET http://ip:port/websocket/left?message=測試消息
- 響應結果:成功返回{“code”:200,“msg”:“操作成功”,“data”:null},失敗返回{“code”:500,“msg”:“操作失敗”,“data”:null}。
六、前端測試(兩種方式)
6.1 在線 WebSocket 測試工具(快速驗證)
推薦使用在線工具:WebSocket 在線測試,無需編寫前端代碼,直接測試連接和消息推送。在線測試網站 https://wstool.js.org/
測試步驟:
- 打開兩個瀏覽器窗口,分別訪問在線測試工具;
- 第一個窗口連接地址填ws://localhost:8080/connect/left,點擊連接,提示 “連接成功”;
- 第二個窗口連接地址填ws://localhost:8080/connect/right,點擊連接,提示 “連接成功”;
- 左屏窗口發(fā)送消息Hello 右屏,右屏窗口會收到左屏推送:Hello 右屏;
- 右屏窗口發(fā)送消息Hello 左屏,左屏窗口會收到右屏推送:Hello 左屏;
- 調用 HTTP 接口http://localhost:8080/websocket/right?message=接口推右屏,右屏窗口會收到該消息。
6.2 自定義 HTML 測試頁面(項目使用)
編寫簡單的 HTML 頁面,通過原生 WebSocket API 實現(xiàn)連接和消息收發(fā),可直接放入項目的resources/static目錄下:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>WebSocket雙屏測試</title>
</head>
<body>
<h3>WebSocket雙屏聯(lián)動測試(<span id="screenType">左屏</span>)</h3>
<input type="text" id="msgInput" placeholder="請輸入消息內容">
<button onclick="sendMsg()">發(fā)送消息</button>
<div id="msgList" style="margin-top: 20px; width: 500px; height: 300px; border: 1px solid #ccc; padding: 10px; overflow-y: auto;"></div>
<script>
// 定義用戶ID,left=左屏,right=右屏
const userId = "left";
document.getElementById("screenType").innerText = userId === "left" ? "左屏" : "右屏";
// WebSocket連接地址,替換為自己的服務端地址
const ws = new WebSocket("ws://localhost:8080/connect/" + userId);
// 連接成功回調
ws.onopen = function() {
addMsg("【系統(tǒng)提示】WebSocket連接成功!");
};
// 接收消息回調
ws.onmessage = function(event) {
addMsg("【收到消息】" + event.data);
};
// 連接關閉回調
ws.onclose = function() {
addMsg("【系統(tǒng)提示】WebSocket連接關閉!");
};
// 連接異常回調
ws.onerror = function() {
addMsg("【系統(tǒng)提示】WebSocket連接異常!");
};
// 發(fā)送消息
function sendMsg() {
const msg = document.getElementById("msgInput").value;
if (!msg) {
alert("請輸入消息內容!");
return;
}
ws.send(msg);
addMsg("【發(fā)送消息】" + msg);
document.getElementById("msgInput").value = "";
}
// 追加消息到頁面
function addMsg(content) {
const msgList = document.getElementById("msgList");
const div = document.createElement("div");
div.style.margin = "5px 0";
div.innerText = new Date().toLocaleString() + " - " + content;
msgList.appendChild(div);
// 滾動到底部
msgList.scrollTop = msgList.scrollHeight;
}
// 心跳檢測,每30秒發(fā)送一次&,防止連接斷開
setInterval(() => {
ws.send("&");
}, 30000);
</script>
</body>
</html>
使用說明:
復制兩份頁面,分別修改userId為left和right,命名為left.html和right.html;
啟動項目后,訪問http://localhost:8080/left.html和http://localhost:8080/right.html;
兩個頁面可互相發(fā)送消息,同時支持后端接口推送。
七、部署方式說明
本文的配置已完美適配Jar 包內嵌 Tomcat和War 包外部 Tomcat兩種部署方式,無需修改任何代碼。
7.1 Jar 包部署(推薦,SpringBoot 默認)
- pom.xml中打包方式為jar:
<packaging>jar</packaging >
- 執(zhí)行 Maven 命令打包:mvn clean package -DskipTests;
- 運行 Jar 包:java -jar xxx.jar;
- 核心原理:內嵌 Tomcat 環(huán)境,WebSocketAutoWired返回true,創(chuàng)建ServerEndpointExporter,WebSocket 正常注冊。
7.2 War 包部署(外部 Tomcat)
- pom.xml中修改打包方式為war,并排除內嵌 Tomcat:
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 排除內嵌Tomcat -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 引入servlet-api依賴 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
- 修改啟動類,繼承SpringBootServletInitializer,重寫configure方法:
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
- 執(zhí)行 Maven 命令打包:mvn clean package -DskipTests;
- 將 war 包放入外部 Tomcat 的webapps目錄,啟動 Tomcat 即可;
- 核心原理:外部 Tomcat 環(huán)境,WebSocketAutoWired返回false,不創(chuàng)建ServerEndpointExporter,由 Tomcat 容器自身初始化 WebSocket,避免沖突。
八、常見問題及解決方案
8.1 客戶端連接報 404 錯誤
原因:未創(chuàng)建ServerEndpointExporter Bean,Spring 未掃描到@ServerEndpoint注解;
解決方案:檢查配置類WebSocketConfig和條件判斷類WebSocketAutoWired是否正確,Jar 包部署時確保matches方法返回true。
8.2 War 包部署到外部 Tomcat 啟動報 Bean 沖突
原因:外部 Tomcat 環(huán)境下創(chuàng)建了ServerEndpointExporter Bean,與容器自身的 WebSocket 初始化沖突;
解決方案:確保條件判斷類WebSocketAutoWired在 War 包部署時返回false,不創(chuàng)建該 Bean。
8.3 發(fā)送消息時報 IO 異常
原因:向失效的 Session(連接已關閉 / 網絡中斷)發(fā)送消息,或未做異常捕獲;
解決方案:在sendMessage方法中增加session.isOpen()判斷,同時捕獲異常并移除失效 Session(本文工具類已實現(xiàn))。
8.4 同一用戶多端登錄,只有最后一個連接能收到消息
原因:原代碼使用Map<String, Session>存儲連接,新連接會覆蓋舊連接;
解決方案:改為Map<String, Set>存儲,同一用戶的所有連接都加入 Set(本文工具類已實現(xiàn))。
8.5 長時間無交互,連接被斷開
原因:防火墻 / 服務器會斷開長時間無數(shù)據(jù)交互的 TCP 連接;
解決方案:實現(xiàn)心跳檢測,客戶端定時發(fā)送心跳包(如&),服務端回執(zhí),保持連接活躍(本文代碼已實現(xiàn))。
九、總結
本文詳細講解了 SpringBoot 集成 WebSocket 的全流程,從核心依賴引入→配置類編寫(解決 Jar/War 兼容)→工具類封裝(連接管理 + 消息發(fā)送)→服務端端點實現(xiàn)(事件處理)→測試接口開發(fā)→前端測試,一步一步實現(xiàn)了雙屏實時消息互推的功能,同時解決了項目開發(fā)和部署中的常見問題。
本文的代碼具有以下特點:
- 高可用性:完善的異常處理、Session 有效性判斷、失效連接清理,避免內存泄漏;
- 高擴展性:工具類和服務端端點解耦,可根據(jù)業(yè)務需求自定義消息處理邏輯;
- 高兼容性:支持 Jar 包和 War 包兩種部署方式,無需手動修改代碼;
- 線程安全:使用 ConcurrentHashMap 和 ConcurrentHashSet 保證多線程下的連接管理安全。
WebSocket 的應用場景非常廣泛,除了雙屏聯(lián)動,還可以用于在線聊天、實時監(jiān)控、訂單推送、彈幕等場景,只需在本文代碼的基礎上,根據(jù)業(yè)務需求修改WebSocketUtils的receive方法和消息發(fā)送邏輯即可。
以上就是SpringBoot集成WebSocket實現(xiàn)雙屏實時消息互推功能的詳細內容,更多關于SpringBoot WebSocket雙屏消息互推的資料請關注腳本之家其它相關文章!
相關文章
mybatis中數(shù)據(jù)加密與解密的實現(xiàn)
數(shù)據(jù)加解密的實現(xiàn)方式多種多樣,在mybatis環(huán)境中數(shù)據(jù)加解密變得非常簡單易用,本文主要介紹了mybatis中數(shù)據(jù)加密與解密的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03
java對象序列化與反序列化的默認格式和json格式使用示例
這篇文章主要介紹了java對象序列化與反序列化的默認格式和json格式使用示例,需要的朋友可以參考下2014-02-02
IDEA 中使用 Big Data Tools 連接大數(shù)據(jù)組件
本文主要介紹了IDEA 中使用 Big Data Tools 連接大數(shù)據(jù)組件,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-05-05
java?stream實現(xiàn)分組BigDecimal求和以及自定義分組求和
這篇文章主要給大家介紹了關于java?stream實現(xiàn)分組BigDecimal求和以及自定義分組求和的相關資料,Stream是Java8的一大亮點,是對容器對象功能的增強,它專注于對容器對象進行各種非常便利、高效的聚合操作或者大批量數(shù)據(jù)操作,需要的朋友可以參考下2023-12-12

