springboot集成WebSockets廣播消息(推薦)
一 WebScoketS 簡(jiǎn)介
RFC 6455 即 webSockets 協(xié)議提供了一種標(biāo)準(zhǔn)化的方式去建立全雙工,雙方面交流的通道在客戶端和服務(wù)端甚至單一的TCP連接中進(jìn)行通信; webSockets 協(xié)議其跟HTTP的tcp協(xié)議不同,但是其設(shè)計(jì)目的是通過(guò)HTTP協(xié)議進(jìn)行工作,可以使用40或者443端口和重新使用現(xiàn)有的防火墻規(guī)則;
GET /spring-websocket-portfolio/portfolio HTTP/1.1 Host: localhost:8080 Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg== Sec-WebSocket-Protocol: v10.stomp, v11.stomp Sec-WebSocket-Version: 13 Origin: http://localhost:8080
webSockets 的交互是以HTTP協(xié)議開始的,使用Upgrade header 轉(zhuǎn)向使用Upgrade連接;如果非200狀態(tài)成功響應(yīng)就類似于下面的信息;如果WebSocket server 是運(yùn)行在nginx是需要配置WebSocket upgrade requests ;如果是運(yùn)行在云上,需要查閱相關(guān)的云是否支持WebSocket ;
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0= Sec-WebSocket-Protocol: v10.stomp
二 HTTP 和 WebSocket 對(duì)比
在HTTP和REST中一個(gè)應(yīng)用需要很多的URLs;應(yīng)用和客戶端是通過(guò) 請(qǐng)求和響應(yīng)的風(fēng)格使用這些URLs進(jìn)行交互;服務(wù)端會(huì)路由這些請(qǐng)求給基于HTTP 的URL或者方法或者頭進(jìn)行處理;
WebSockets 通常在初始化的時(shí)候就只有一個(gè)鏈接,所有應(yīng)用的消息都是通過(guò)相同的TCP連接進(jìn)行流動(dòng);這指向一個(gè)完全不同的異步、事件驅(qū)動(dòng)的消息傳遞體系結(jié)構(gòu)。
WebSocket 是一種低端的協(xié)議,不像HTTP,其不規(guī)定消息中內(nèi)容中任何的語(yǔ)義信息;這意味著其沒(méi)有任何方式去路由或者處理這些信息,除非客戶端和服務(wù)端在語(yǔ)義上達(dá)成一致;
WebSocket 客戶端和服務(wù)端其交流是通過(guò)使用更加高級(jí)的消息協(xié)議(比如STOMP)和基于HTTP握手請(qǐng)求的Sec-WebSocket-Protocol header ;
三 注意事項(xiàng)
WebSockets可以使web頁(yè)面具有動(dòng)態(tài)性和交互性。然而,在許多情況下,Ajax和HTTP流或 long polling(輪詢)可以提供一個(gè)簡(jiǎn)單有效的解決方案。HTTP流和polling適用于消息不頻繁的交互,WebSockets適用于消息較頻繁的交互;在 因特網(wǎng)上由于沒(méi)有Upgrade header 或者 關(guān)閉了空閑的長(zhǎng)鏈接,受限于在你有限的代理可能會(huì)將WebSockets的交互排除;
四 websocket配置和依賴
4.1 依賴
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.1.RELEASE</version> <relativePath/> </parent> <dependencies> <!-- websocket依賴--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> <!-- 模板引擎--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> </dependencies>
4.2 配置
/** * @Author lsc * @Description <p>websocket配置類 </p> * @Date 2019/11/12 22:27 */ //使用STOMP協(xié)議來(lái)傳輸基于消息代理的消息,控制器支持在@Controller類中使用@MessageMapping @EnableWebSocketMessageBroker @Configurable @EnableWebSocket @Component public class WebConfig implements WebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry registry) { // 注冊(cè) Stomp的端點(diǎn)(Endpoint),并且映射指定的url registry.addEndpoint("/websocket") .setAllowedOrigins("*") // 添加允許跨域訪問(wèn) .withSockJS();// 指定SockJS協(xié)議 } @Override public void configureMessageBroker(MessageBrokerRegistry registry) { // 啟動(dòng)廣播模式代理,只有符合的的路徑才發(fā)送消息 registry.enableSimpleBroker("/topic"); } }
五 實(shí)體類
5.1 接受消息實(shí)體
/** * @Author lsc * @Description <p> 接受客戶端消息</p> * @Date 2019/11/12 22:42 */ public class AcceptMessages { private String name; public String getName() { return name; } }
5.2 發(fā)送消息實(shí)體
/** * @Author lsc * @Description <p>發(fā)送消息給客戶端 </p> * @Date 2019/11/12 22:42 */ public class SendMessages { private String responseMessage; public String getResponseMessage() { return responseMessage; } public void setResponseMessage(String responseMessage) { this.responseMessage = responseMessage; } }
六控制器
/** * @Author lsc * @Description <p>websockets 之 廣播式</p> * @Date 2019/11/12 22:49 */ @Controller public class WebSocketsController { @MessageMapping("/welcome")//類似@RequestMapping,進(jìn)行客戶端請(qǐng)求地址映射 @SendTo("/topic/getResponse")//訂閱了@SendTo中的路徑進(jìn)行發(fā)送消息 public SendMessages broadcast(AcceptMessages acceptMessages){ System.out.println(acceptMessages.getName()); SendMessages sendMessages = new SendMessages(); sendMessages.setResponseMessage("知識(shí)追尋者:"+acceptMessages.getName()); return sendMessages; } }
七 前端頁(yè)面
在 resource目錄下新建templates目錄存放WebSockets.html;在resource目錄下新建static目錄,繼續(xù)在其子目錄下新建js目錄存放sockjs.min.js,stomp.min.js,jquery-3.3.1.min.js;
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"/> <title>springboot廣播式WebSocket</title> </head> <body onload="disconnect()"> <noscript><h2 style="color: #ffff0000;">Sorry,not support the WebSocket</h2></noscript> <div> <div> <button id="connect" onclick="connect();">連接</button> <button id="disconnect" disabled="disabled" onclick="disconnect();">斷開連接</button> </div> <div id="conversationDiv"> <label>輸入你的名字</label> <input type="text" id="name"/> <button id="sendName" onclick="sendName();">發(fā)送</button> <p id="response"></p> </div> </div> <script th:src="@{js/sockjs.min.js}"></script> <script th:src="@{js/stomp.min.js}"></script> <script th:src="@{js/jquery-3.3.1.min.js}"></script> <script type="text/javascript"> var stompClient = null; // 設(shè)置連接 function setConnected(connected) { document.getElementById("connect").disabled = connected; document.getElementById("disconnect").disabled = !connected; document.getElementById("conversationDiv").style.visibility = connected ? 'visible' : 'hidden'; $("#response").html(); } // 連接 function connect() { // 轉(zhuǎn)向 endpoint 名為websocket var socket = new SockJS('/websocket'); // 使用ssocket的協(xié)議 stompClient = Stomp.over(socket); // 連接 stompClient.connect({}, function (frame) { setConnected(true); console.log('Connected:' + frame); // @Sendto 中定義路徑 向目標(biāo)訂閱消息 stompClient.subscribe('/topic/getResponse', function (response) { showResponse(JSON.parse(response.body).responseMessage); }) }); } function disconnect() { if (stompClient != null) { stompClient.disconnect(); } setConnected(false); console.log('Disconnected'); } function sendName() { var name = $('#name').val(); // 控制器@MessageMapping中定義向目標(biāo)發(fā)送消息 stompClient.send("/welcome", {}, JSON.stringify({'name': name})); } function showResponse(message) { $("#response").html(message); } </script> </body> </html>
八 視圖轉(zhuǎn)發(fā)
當(dāng)客戶端請(qǐng)求地址是localhost:8080/ws,經(jīng)過(guò)springmvc視圖轉(zhuǎn)發(fā)器至WebSockets.html;
/** * @Author lsc * @Description <p> spingmvc視圖映射轉(zhuǎn)發(fā)</p> * @Date 2019/11/12 23:35 */ @Configurable @Component public class WebMvcConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { // 配置視圖轉(zhuǎn)發(fā) registry.addViewController("/ws").setViewName("/WebSockets"); } }
九 效果圖
即一個(gè)瀏覽器發(fā)送消息,其它連接的瀏覽器也能收到消息,即廣播形式;
十 參考文獻(xiàn)
spring-web
源碼
總結(jié)
以上所述是小編給大家介紹的springboot集成WebSockets廣播消息,希望對(duì)大家有所幫助!
上一篇:java8 stream的分組功能實(shí)例介紹
欄 目:Java
下一篇:Spring Boot企業(yè)常用的starter示例詳解
本文標(biāo)題:springboot集成WebSockets廣播消息(推薦)
本文地址:http://mengdiqiu.com.cn/a1/Java/8806.html
您可能感興趣的文章
- 01-10Springboot中@Value的使用詳解
- 01-10springboot實(shí)現(xiàn)文件上傳步驟解析
- 01-10springboot jta atomikos實(shí)現(xiàn)分布式事物管理
- 01-10SpringBoot使用RabbitMQ延時(shí)隊(duì)列(小白必備)
- 01-10如何基于SpringBoot部署外部Tomcat過(guò)程解析
- 01-10springboot集成fastDfs過(guò)程代碼實(shí)例
- 01-10SPRINGBOOT讀取PROPERTIES配置文件數(shù)據(jù)過(guò)程詳解
- 01-10springboot 配置DRUID數(shù)據(jù)源的方法實(shí)例分析
- 01-10springboot2.0使用Hikari連接池的方法(替換druid)
- 01-10springboot單元測(cè)試兩種方法實(shí)例詳解


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-10Java實(shí)現(xiàn)動(dòng)態(tài)模擬時(shí)鐘
- 01-10Springboot中@Value的使用詳解
- 01-10JavaWeb實(shí)現(xiàn)郵件發(fā)送功能
- 01-10利用Java實(shí)現(xiàn)復(fù)制Excel工作表功能
- 01-10Java實(shí)現(xiàn)動(dòng)態(tài)數(shù)字時(shí)鐘
- 01-10java基于poi導(dǎo)出excel透視表代碼實(shí)例
- 01-10java實(shí)現(xiàn)液晶數(shù)字字體顯示當(dāng)前時(shí)間
- 01-10基于Java驗(yàn)證jwt token代碼實(shí)例
- 01-10Java動(dòng)態(tài)顯示當(dāng)前日期和時(shí)間
- 01-10淺談Java中真的只有值傳遞么
隨機(jī)閱讀
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-10delphi制作wav文件的方法
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10C#中split用法實(shí)例總結(jié)
- 04-02jquery與jsp,用jquery
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子