久久福利_99r_国产日韩在线视频_直接看av的网站_中文欧美日韩_久久一

您的位置:首頁技術(shù)文章
文章詳情頁

SpringBoot集成WebSocket長連接實(shí)際應(yīng)用詳解

瀏覽:54日期:2023-05-12 15:52:11

前言:

一、WebSocket之初出茅驢

官方定義:WebSocket是一種在單個(gè)TCP連接上進(jìn)行全雙工通信的協(xié)議。WebSocket使得客戶端和服務(wù)器之間的數(shù)據(jù)交換變得更加簡單,允許服務(wù)端主動(dòng)向客戶端推送數(shù)據(jù)。在WebSocket API中,瀏覽器和服務(wù)器只需要完成一次握手,兩者之間就直接可以創(chuàng)建持久性的連接,并進(jìn)行雙向數(shù)據(jù)傳輸。是真正的雙向平等對(duì)話,屬于服務(wù)器推送技術(shù)的一種。

太官方啦,還是博主過來翻譯一下吧 :WebSocket技術(shù)只需要service和client建立一次連接,就能實(shí)現(xiàn)服務(wù)器和客戶端雙方相互頻繁的發(fā)送請(qǐng)求和通信!(簡單加粗暴的翻譯有木有,哈哈!)

WebSocket經(jīng)典的使用場(chǎng)景:網(wǎng)站在線聊天系統(tǒng)、彈幕系統(tǒng)…

臣附議:webSocket技術(shù)無法做到向下兼容,不兼容低版本的IE,因此依賴于瀏覽器版本,這也正是webSocket非常顯著的缺陷。

二、WebSocket的出現(xiàn)到底為我們解決了什么實(shí)際問題?

在傳統(tǒng)的b/s架構(gòu)中,要實(shí)現(xiàn)服務(wù)器向client進(jìn)行實(shí)時(shí)消息推送功能,市場(chǎng)上常用的解決方案大致分為三類:

定時(shí)輪詢 客戶端以一定的時(shí)間間隔向服務(wù)端發(fā)出請(qǐng)求 長輪詢 如果服務(wù)器沒有可以立即返回給客戶端的數(shù)據(jù),則不會(huì)立刻返回一個(gè)空結(jié)果 流技術(shù) 客戶端隱藏的窗口向服務(wù)端發(fā)出一個(gè)長輪詢的請(qǐng)求

長輪詢機(jī)制:

SpringBoot集成WebSocket長連接實(shí)際應(yīng)用詳解

綜合這幾種方案,您會(huì)發(fā)現(xiàn)這些目前我們所使用的所謂的實(shí)時(shí)技術(shù)并不是真正的實(shí)時(shí)技術(shù),它們只是在用 Ajax 方式來模擬實(shí)時(shí)的效果,定時(shí)輪詢需要實(shí)時(shí)獲取取服務(wù)端信息的應(yīng)用時(shí), client需要頻繁輪詢server,為了拿到最新信息, client一直這樣循環(huán)下去server如果一直沒有新的消息, client的大多請(qǐng)求都是屬于無效請(qǐng)求, 導(dǎo)致會(huì)帶來很多無謂的網(wǎng)絡(luò)傳輸,所以這是一種非常低效的實(shí)時(shí)方案。長輪詢對(duì)服務(wù)器造成的壓力非常大,并且如果服務(wù)端的數(shù)據(jù)變更非常頻繁的話,這種方式無異于定時(shí)輪詢。所以為了解決傳統(tǒng)http請(qǐng)求的實(shí)際問題,WebSocket技術(shù)應(yīng)運(yùn)而生!下面博主給張圖讓大家生動(dòng)的理解傳統(tǒng)HTTP和WebSocket的差異化:

SpringBoot集成WebSocket長連接實(shí)際應(yīng)用詳解

三、博主使用WebSocket的場(chǎng)景

博主最進(jìn)在公司調(diào)用第三方影像采集系統(tǒng),由于影像狀態(tài)是異步返回給業(yè)務(wù)系統(tǒng)的,導(dǎo)致當(dāng)業(yè)務(wù)系統(tǒng)收到第三方回調(diào)后,對(duì)于前臺(tái)用戶體驗(yàn)來說是無感知的,因此前臺(tái)必須刷新頁面才能獲取到影像最新狀態(tài)。這時(shí)候由service主動(dòng)向client實(shí)時(shí)發(fā)送影像采集狀態(tài)的通知是最好不過的方案!在上述提到的常用解決方案,像輪詢這種比較low的實(shí)現(xiàn),博主作為技術(shù)宅,肯定是不會(huì)作為技術(shù)選型的,哈哈…

四、不多bb,上代碼!

本項(xiàng)目是基于SpringBoot環(huán)境開發(fā)

1、導(dǎo)入websocket坐標(biāo)

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId></dependency>

2、封裝WebSocketUtil工具類,用于提供對(duì)session鏈接、斷開連接、推送消息的簡單控制。

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è)連接,我們視為無效。 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)); }}

3、 WebSocketController

如上,已經(jīng)創(chuàng)建好了簡單的session管理和消息管理,接下來要使用注解的方式,使用SpringBoot的websocket包提供的方法,實(shí)現(xiàn)OnOpen、OnClose、OnMessage三個(gè)方法,再實(shí)現(xiàn)一個(gè)OnError方法來應(yīng)對(duì)異常。代碼段如下:

/** * 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 ); } /** * 連接事件,加入注解 * 用戶斷開鏈接 * @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; // 直接廣播 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(); }}

4、添加 ServerEndpointExporter 啟動(dòng)Bean

public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } /** * 會(huì)自動(dòng)注冊(cè)使用了@ServerEndpoint注解聲明的Websocket endpoint * 要注意,如果使用獨(dú)立的servlet容器, * 而不是直接使用springboot的內(nèi)置容器, * 就不要注入ServerEndpointExporter,因?yàn)樗鼘⒂扇萜髯约禾峁┖凸芾怼? */ @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); }}

那些年踩過的坑:注意:在websocketEndpoint中,使用@Autowired一些列注解注入Bean時(shí)候,一直無法注入,報(bào)空指針。原因在于spring管理的都是單例(singleton),和 websocket (多對(duì)象)相沖突。解決辦法:通過上下文獲取bean實(shí)例:從Spring上下文獲取bean實(shí)例的方法

到此這篇關(guān)于SpringBoot集成WebSocket長連接實(shí)際應(yīng)用詳解的文章就介紹到這了,更多相關(guān)SpringBoot WebSocket長連接內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Spring
相關(guān)文章:
主站蜘蛛池模板: 国产一区二区视频在线观看 | 国产免费久久 | 国产精品亚洲区 | 一级做a爰性色毛片免费1 | 亚洲精品v日韩精品 | 一区二区国产在线观看 | 国产精品日韩三级 | 婷色综合 | 欧美精品成人一区二区三区四区 | 99re视频在线观看 | 成人av观看 | 国产成人片 | 久久久www成人免费无遮挡大片 | 成人欧美 | 欧美精品日韩 | 日韩免费视频中文字幕 | 色先锋av资源中文字幕 | 噜噜噜天天躁狠狠躁夜夜精品 | 色综合久| 精品国产髙清在线看国产毛片 | 中文字幕在线电影 | 色吊丝2288sds中文字幕 | 看毛片网站 | 国产黄色一级大片 | 午夜电影网址 | 黄网站在线播放 | 免费观看一级特黄欧美大片 | 天天拍天天操 | av中文字幕网 | 色婷婷国产精品久久包臀 | 精品久久久久一区二区国产 | 红桃成人少妇网站 | 久久久久久久久免费视频 | 国产精品影院在线观看 | 欧美日韩a v | 国产精品视频一区二区三区不卡 | 日韩欧美一区二区三区免费观看 | 欧美日韩一区二区三区 | 天天爱天天草 | 午夜影视 | 国产精品久久久久久久久福交 |