springboot websocket簡(jiǎn)單入門(mén)示例
之前做的需求都是客戶端請(qǐng)求服務(wù)器響應(yīng),新需求是服務(wù)器主動(dòng)推送信息到客戶端.百度之后有流、長(zhǎng)輪詢、websoket等方式進(jìn)行.但是目前更加推崇且合理的顯然是websocket.
從springboot官網(wǎng)翻譯了一些資料,再加上百度簡(jiǎn)單實(shí)現(xiàn)了springboot使用websocekt與客戶端的雙工通信.
1.首先搭建一個(gè)簡(jiǎn)單的springboot環(huán)境
<!-- Inherit defaults from Spring Boot --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.4.RELEASE</version> </parent> <!-- Add typical dependencies for a web application --> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
2.引入springboot整合websocket依賴
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-websocket --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> <version>2.0.4.RELEASE</version> </dependency>
3.創(chuàng)建啟動(dòng)springboot的核心類(lèi)
package com; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class GlobalConfig { public static void main(String[] args) { SpringApplication.run(GlobalConfig.class, args); } }
4.創(chuàng)建websocket服務(wù)器
正如springboot 官網(wǎng)推薦的websocket案例,需要實(shí)現(xiàn)WebSocketHandler或者繼承TextWebSocketHandler/BinaryWebSocketHandler當(dāng)中的任意一個(gè).
package com.xiaoer.handler; import com.alibaba.fastjson.JSONObject; import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.handler.TextWebSocketHandler; import java.util.HashMap; import java.util.Map; /** * 相當(dāng)于controller的處理器 */ public class MyHandler extends TextWebSocketHandler { @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { String payload = message.getPayload(); Map<String, String> map = JSONObject.parseObject(payload, HashMap.class); System.out.println("=====接受到的數(shù)據(jù)"+map); session.sendMessage(new TextMessage("服務(wù)器返回收到的信息," + payload)); } }
5.注冊(cè)處理器
package com.xiaoer.config; import com.xiaoer.handler.MyHandler; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(myHandler(), "myHandler/{ID}"); } public WebSocketHandler myHandler() { return new MyHandler(); } }
6.運(yùn)行訪問(wèn)
出現(xiàn)如上圖是因?yàn)椴荒苤苯油ㄟ^(guò)http協(xié)議訪問(wèn),需要通過(guò)html5的ws://協(xié)議進(jìn)行訪問(wèn).
7.創(chuàng)建Html5 客戶端
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <body> <input id="text" type="text" /> <button onclick="send()">Send</button> <button onclick="closeWebSocket()">Close</button> <div id="message"> </div> <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script> <script> var userID="888"; var websocket=null; $(function(){ connectWebSocket(); }) //建立WebSocket連接 function connectWebSocket(){ console.log("開(kāi)始..."); //建立webSocket連接 websocket = new WebSocket("ws://127.0.0.1:8080/myHandler/ID="+userID); //打開(kāi)webSokcet連接時(shí),回調(diào)該函數(shù) websocket.onopen = function () { console.log("onpen"); } //關(guān)閉webSocket連接時(shí),回調(diào)該函數(shù) websocket.onclose = function () { //關(guān)閉連接 console.log("onclose"); } //接收信息 websocket.onmessage = function (msg) { console.log(msg.data); } } //發(fā)送消息 function send(){ var postValue={}; postValue.id=userID; postValue.message=$("#text").val(); websocket.send(JSON.stringify(postValue)); } //關(guān)閉連接 function closeWebSocket(){ if(websocket != null) { websocket.close(); } } </script> </body> </html>
8.運(yùn)行
利用客戶端運(yùn)行之后仍然會(huì)出現(xiàn)上圖中的一連接就中斷了websocket連接.
這是因?yàn)閟pring默認(rèn)不接受跨域訪問(wèn):
As of Spring Framework 4.1.5, the default behavior for WebSocket and SockJS is to accept only same origin requests.
需要在WebSocketConfig中設(shè)置setAllowedOrigins.
package com.xiaoer.config; import com.xiaoer.handler.MyHandler; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(myHandler(), "myHandler/{ID}") .setAllowedOrigins("*"); } public WebSocketHandler myHandler() { return new MyHandler(); } }
如下圖,并未輸出中斷,說(shuō)明連接成功.
9.服務(wù)器和客戶端的相互通信
服務(wù)器端收到消息
客戶端收到服務(wù)器主動(dòng)推送消息
以上就是一個(gè)最基礎(chǔ)的springboot簡(jiǎn)單應(yīng)用.還可以通過(guò)攔截器、重寫(xiě)WebSocketConfigurer中的方法進(jìn)行更為復(fù)雜的屬性操作.具體可以參考SpringBoot集成WebSocket【基于純H5】進(jìn)行點(diǎn)對(duì)點(diǎn)[一對(duì)一]和廣播[一對(duì)多]實(shí)時(shí)推送
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot請(qǐng)求參數(shù)相關(guān)注解說(shuō)明小結(jié)
這篇文章主要介紹了SpringBoot請(qǐng)求參數(shù)相關(guān)注解說(shuō)明,主要包括@PathVariable,@RequestHeader、@CookieValue、@RequestBody和@RequestParam,本文結(jié)合實(shí)例代碼給大家講解的非常詳細(xì),需要的朋友可以參考下2022-05-05Spring Boot Actuator監(jiān)控的簡(jiǎn)單使用方法示例代碼詳解
這篇文章主要介紹了Spring Boot Actuator監(jiān)控的簡(jiǎn)單使用,本文通過(guò)實(shí)例代碼圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06SpringBoot基于Sentinel在服務(wù)上實(shí)現(xiàn)接口限流
這篇文章主要介紹了SpringBoot基于Sentinel在服務(wù)上實(shí)現(xiàn)接口限流,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10java實(shí)現(xiàn)角色及菜單權(quán)限的項(xiàng)目實(shí)踐
在Java中,實(shí)現(xiàn)角色及菜單權(quán)限管理涉及定義實(shí)體類(lèi)、設(shè)計(jì)數(shù)據(jù)庫(kù)表、實(shí)現(xiàn)服務(wù)層和控制器層,這種管理方式有助于有效控制用戶權(quán)限,適用于企業(yè)級(jí)應(yīng)用,感興趣的可以一起來(lái)了解一下2024-09-09