SpringBoot使用WebSocket實(shí)現(xiàn)向前端推送消息功能
WebSocket簡(jiǎn)介
WebSocket協(xié)議是基于TCP的一種新的網(wǎng)絡(luò)協(xié)議。它實(shí)現(xiàn)了瀏覽器與服務(wù)器全雙工(full-duplex)通信——允許服務(wù)器主動(dòng)發(fā)送信息給客戶端。
SpringBoot整合WebSocket的相關(guān)依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency> WebSokcet工具類記錄當(dāng)前的在線連接對(duì)鏈接進(jìn)行操作
public class WebsocketUtil {
/**
* 記錄當(dāng)前在線的Session
*/
private static final Map<String, Session> ONLINE_SESSION = new ConcurrentHashMap<>();
/**
* 添加session
* @param userId
* @param session
*/
public static void addSession(String userId, Session session){
// 此處只允許一個(gè)用戶的session鏈接。一個(gè)用戶的多個(gè)連接,我們視為無(wú)效。
ONLINE_SESSION.putIfAbsent ( userId, session );
}
/**
* 關(guān)閉session
* @param userId
*/
public static void removeSession(String userId){
ONLINE_SESSION.remove ( userId );
}
/**
* 給單個(gè)用戶推送消息
* @param session
* @param message
*/
public static void sendMessage(Session session, String message){
if(session == null){
return;
}
// 同步
RemoteEndpoint.Async async = session.getAsyncRemote ();
async.sendText ( message );
}
/**
* 向所有在線人發(fā)送消息
* @param message
*/
public static void sendMessageForAll(String message) {
//jdk8 新方法
ONLINE_SESSION.forEach((sessionId, session) -> sendMessage(session, message));
}
}
WebSocket接口處理類
/**
* websocket接口處理類
*/
@Component
@ServerEndpoint(value = "/chat/{userId}")
public class WebsocketController {
/**
* 連接事件,加入注解
* @param userId
* @param session
*/
@OnOpen
public void onOpen(@PathParam(value = "userId") String userId, Session session) {
String message = "[" + userId + "]加入聊天室??!";
// 添加到session的映射關(guān)系中
WebsocketUtil.addSession(userId, session);
// 廣播通知,某用戶上線了
// WebsocketUtil.sendMessageForAll(message);
}
/**
* 連接事件,加入注解
* 用戶斷開(kāi)鏈接
*
* @param userId
* @param session
*/
@OnClose
public void onClose(@PathParam(value = "userId") String userId, Session session) {
String message = "[" + userId + "]退出了聊天室...";
// 刪除映射關(guān)系
WebsocketUtil.removeSession(userId);
// 廣播通知,用戶下線了
WebsocketUtil.sendMessageForAll(message);
}
/**
* 當(dāng)接收到用戶上傳的消息
*
* @param userId
* @param session
*/
@OnMessage
public void onMessage(@PathParam(value = "userId") String userId, Session session, String message) {
String msg = "[" + userId + "]:" + message;
System.out.println("接收到信息:" + msg);
// 直接廣播
WebsocketUtil.sendMessageForAll(msg);
}
/**
* 處理用戶活連接異常
*
* @param session
* @param throwable
*/
@OnError
public void onError(Session session, Throwable throwable) {
try {
session.close();
} catch (IOException e) {
e.printStackTrace();
}
throwable.printStackTrace();
}
}
服務(wù)器端單個(gè)用戶推送消息
@PostMapping("/send")
public void send(@RequestParam("id") String id,@RequestParam("message")String message) {
Session session = ONLINE_SESSION.get(id);
WebsocketUtil.sendMessage(session,message);
System.out.println("發(fā)送成功");
}
使用Apifox進(jìn)行測(cè)試
添加連接服務(wù)端的WebSocket接口

連接成功:

服務(wù)端推送消息

客戶端收到的消息

WebSocket工具類里面有群發(fā)的方法,大家想用可以直接調(diào)用,這里就不進(jìn)行演示了
問(wèn)題一:如何在上面WebSocket接口處理類中注入其他的Bean?
我也是在一次工作中遇到這樣的問(wèn)題,今天正好和大家講一下如何解決
查閱資料才知道WebSocket接口處理類使用@ServerEndPoint注解表明他是一個(gè)WebSocket端點(diǎn),因此Spring不會(huì)將其納入Spring容器的管理范圍,WebSocket的生命周期和Spring Bean 的生命周期并不一致,所以通過(guò)@Autowired 注解注入得到的都是空的Bean 無(wú)法使用
我們自定義一個(gè)工具類手動(dòng)獲取Bean在 WebSocket接口處理類中使用:
/**
*AppUtils類
*
* @author qiancj
* @since 2020-06-30 13:02
*/
@Component("appUtils")
public class AppUtils {
/**
* 應(yīng)用上下文
*/
private static ApplicationContext context;
@Resource
public void setApplicationContext(ApplicationContext c) {
context = c;
}
/**
* 獲取配置參數(shù)
*
* @param property 配置參數(shù)名
* @return 配置參數(shù)值
*/
public static String getProperty(String property) {
return context.getEnvironment().getProperty(property);
}
/**
* 獲取bean對(duì)象
*
* @param requiredType Class
* @param <T> T
* @return bean對(duì)象
*/
public static <T> T getBean(Class<T> requiredType) {
return context.getBean(requiredType);
}
/**
* 獲取bean對(duì)象
*
* @param name bean name
* @param requiredType Class
* @param <T> T
* @return bean對(duì)象
*/
public static <T> T getBean(String name, Class<T> requiredType) {
return context.getBean(requiredType);
}
}
使用:
MessageService messageService = AppUtils.getBean(MessageService.class);
然后我們就可以使用messageService調(diào)用Service層相關(guān)的方法了。
問(wèn)題解決。
以上就是SpringBoot使用WebSocket實(shí)現(xiàn)向前端推送消息功能的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot WebSocket推送消息的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- SpringBoot集成WebSocket實(shí)現(xiàn)后臺(tái)向前端推送信息的示例
- SpringBoot2.0集成WebSocket實(shí)現(xiàn)后臺(tái)向前端推送信息
- Spring?Boot?使用?SSE?方式向前端推送數(shù)據(jù)詳解
- SpringBoot整合WebSocket實(shí)現(xiàn)后端向前端主動(dòng)推送消息方式
- SpringBoot集成WebSocket實(shí)現(xiàn)后臺(tái)向前端推送信息
- SpringBoot+WebSocket向前端推送消息的實(shí)現(xiàn)示例
- 利用Netty+SpringBoot實(shí)現(xiàn)定時(shí)后端向前端推送數(shù)據(jù)
相關(guān)文章
Javax Validation自定義注解進(jìn)行身份證號(hào)校驗(yàn)
這篇文章主要為大家詳細(xì)介紹了如何通過(guò)Javax Validation自定義注解進(jìn)行身份證號(hào)校驗(yàn),文中的示例代碼講解詳細(xì),有需要的小伙伴可以參考一下2024-10-10
如何解決創(chuàng)建maven工程時(shí),產(chǎn)生“找不到插件的錯(cuò)誤”問(wèn)題
這篇文章主要介紹了如何解決創(chuàng)建maven工程時(shí),產(chǎn)生“找不到插件的錯(cuò)誤”問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
實(shí)例講解Java設(shè)計(jì)模式編程中如何運(yùn)用代理模式
這篇文章主要介紹了Java設(shè)計(jì)模式編程中如何運(yùn)用代理模式,文中舉了普通代理和強(qiáng)制代理的例子作為代理模式的擴(kuò)展內(nèi)容,需要的朋友可以參考下2016-02-02
Windows下Dubbo+Zookeeper實(shí)現(xiàn)分布式部署教程
本文介紹了如何使用Dubbo和Zookeeper搭建分布式服務(wù),包括環(huán)境準(zhǔn)備、項(xiàng)目結(jié)構(gòu)、依賴引入、接口與服務(wù)實(shí)現(xiàn)、注解配置及服務(wù)調(diào)用流程,適合初學(xué)者參考和實(shí)踐2025-10-10
Java使用FastExcel實(shí)現(xiàn)合并單元格
FastExcel 是一個(gè)采用純 java 開(kāi)發(fā)的 excel 文件讀寫組件,支持 Excel'97(-2003)(BIFF8)文件格式,本文主要介紹了如何使用FastExcel實(shí)現(xiàn)合并單元格,需要的可以參考下2024-12-12
IntelliJ?IDEA導(dǎo)出WAR包詳細(xì)過(guò)程
這篇文章主要介紹了IntelliJ?IDEA導(dǎo)出WAR包全指南,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2026-01-01

