Spring Boot 中的 SockJS原理及使用方法
Spring Boot 中的 SockJS
在 Spring Boot 中,SockJS
是一個用于實(shí)現(xiàn) WebSocket 的兼容性解決方案。本文將介紹 SockJS
的原理、使用方法和示例代碼。
什么是 SockJS
SockJS
是一種瀏覽器與服務(wù)器之間的通信協(xié)議,它可以在瀏覽器和服務(wù)器之間建立一個基于 HTTP 的雙向通信通道。SockJS
的主要作用是提供一種 WebSocket 的兼容性解決方案,使得不支持 WebSocket 的瀏覽器也可以使用 WebSocket。
SockJS
實(shí)現(xiàn)了一個 WebSocket 的兼容層,它可以在瀏覽器和服務(wù)器之間建立一個基于 HTTP 的通信通道,然后通過這個通道進(jìn)行雙向通信。當(dāng)瀏覽器不支持 WebSocket 時(shí),SockJS
會自動切換到使用輪詢(polling)或長輪詢(long-polling)的方式進(jìn)行通信。
SockJS 的原理
SockJS
的原理是通過建立一個基于 HTTP 的通信通道來實(shí)現(xiàn) WebSocket 的雙向通信。當(dāng)瀏覽器支持 WebSocket 時(shí),SockJS
會直接使用 WebSocket 進(jìn)行通信;當(dāng)瀏覽器不支持 WebSocket 時(shí),SockJS
會自動切換到使用輪詢(polling)或長輪詢(long-polling)的方式進(jìn)行通信。
在使用 SockJS
時(shí),首先需要在客戶端和服務(wù)器端分別引入 sockjs-client.js
和 sockjs-server
,然后在客戶端通過 new SockJS(url)
的方式建立一個 SockJS
連接。
客戶端和服務(wù)器端之間的通信是基于事件的,當(dāng)客戶端發(fā)送消息時(shí),服務(wù)器端會觸發(fā)一個 onmessage
事件,然后將消息發(fā)送回客戶端??蛻舳嗽诮邮盏较⒑?,會觸發(fā)一個 onmessage
事件,然后處理收到的消息。
如何使用 SockJS
使用 SockJS
非常簡單,在 Spring Boot 中,只需要在配置文件中添加以下內(nèi)容即可:
spring: websocket: enabled: true broker: relay-host: localhost relay-port: 61613 user: guest password: guest relay-path: /stomp
以上配置表示啟用 WebSocket,并將消息發(fā)送到 localhost
的 61613
端口,使用 guest/guest
的用戶名和密碼進(jìn)行認(rèn)證,使用 /stomp
路徑進(jìn)行消息傳輸。
接下來,我們需要在客戶端中建立一個 SockJS
連接,并實(shí)現(xiàn) onmessage
事件的回調(diào)方法。代碼如下:
var socket = new SockJS('/gs-guide-websocket'); stompClient = Stomp.over(socket); stompClient.connect({}, function(frame) { stompClient.subscribe('/topic/greetings', function(greeting){ showGreeting(JSON.parse(greeting.body).content); }); });
以上代碼中,new SockJS('/gs-guide-websocket')
表示使用 /gs-guide-websocket
路徑建立一個 SockJS
連接。stompClient.connect({}, function(frame){...})
表示連接成功后執(zhí)行的回調(diào)方法,stompClient.subscribe('/topic/greetings', function(greeting){...})
表示訂閱 /topic/greetings
目的地,當(dāng)有消息發(fā)布到該目的地時(shí)觸發(fā)回調(diào)方法。
最后,我們需要在服務(wù)器端實(shí)現(xiàn)消息發(fā)送和接收的功能。代碼如下:
@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.enableStompBrokerRelay("/topic") .setRelayHost("localhost") .setRelayPort(61613) .setClientLogin("guest") .setClientPasscode("guest") .setSystemHeartbeatSendInterval(5000) .setSystemHeartbeatReceiveInterval(4000); registry.setApplicationDestinationPrefixes("/app"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/gs-guide-websocket").withSockJS(); } }
以上代碼中,@EnableWebSocketMessageBroker
注解表示啟用 WebSocket 消息代理,configureMessageBroker
方法用于配置消息代理,registerStompEndpoints
方法用于注冊 SockJS
端點(diǎn)。
接下來,我們需要在控制器中實(shí)現(xiàn)消息發(fā)送和接收的功能。代碼如下:
@Controller public class GreetingController { @MessageMapping("/hello") @SendTo("/topic/greetings") public Greeting greeting(HelloMessage message) throws Exception { Thread.sleep(1000); // simulated delay return new Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!"); } }
以上代碼中,@MessageMapping("/hello")
注解表示處理 /hello
目的地的消息,@SendTo("/topic/greetings")
注解表示將處理結(jié)果發(fā)送到 /topic/greetings
目的地。greeting
方法實(shí)現(xiàn)了消息的處理邏輯。
示例代碼
以下是一個完整的示例代碼,包括客戶端和服務(wù)器端的代碼:
客戶端代碼
<!DOCTYPE html> <html> <head> <title>Hello WebSocket</title> <script src="/webjars/sockjs-client/1.1.2/dist/sockjs.min.js"></script> <script src="/webjars/stomp-websocket/2.3.3/dist/stomp.min.js"></script> <script src="/js/app.js"></script> </head> <body> <div> <label>What is your name?</label> <input type="text" id="name" /> <button type="button" onclick="send()">Send</button> </div> <div id="greetings"> </div> </body> </html>
var socket = new SockJS('/gs-guide-websocket'); stompClient = Stomp.over(socket); stompClient.connect({}, function(frame) { stompClient.subscribe('/topic/greetings', function(greeting){ showGreeting(JSON.parse(greeting.body).content); }); }); function send() { var name = document.getElementById('name').value; stompClient.send("/app/hello", {}, JSON.stringify({ 'name': name })); } function showGreeting(message) { var div = document.createElement('div'); div.appendChild(document.createTextNode(message)); document.getElementById('greetings').appendChild(div); }
服務(wù)器端代碼
@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.enableStompBrokerRelay("/topic") .setRelayHost("localhost") .setRelayPort(61613) .setClientLogin("guest") .setClientPasscode("guest") .setSystemHeartbeatSendInterval(5000) .setSystemHeartbeatReceiveInterval(4000); registry.setApplicationDestinationPrefixes("/app"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/gs-guide-websocket").withSockJS(); } } @Controller public class GreetingController { @MessageMapping("/hello") @SendTo("/topic/greetings") public Greeting greeting(HelloMessage message) throws Exception { Thread.sleep(1000); // simulated delay return new Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!"); } } public class HelloMessage { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } public class Greeting { private String content; public Greeting(String content) { this.content = content; } public String getContent() { return content; } }
以上代碼實(shí)現(xiàn)了一個簡單的聊天室,用戶在輸入框中輸入自己的名字,然后點(diǎn)擊發(fā)送按鈕,將消息發(fā)送到服務(wù)器端,服務(wù)器端將收到的消息處理后發(fā)送回客戶端,客戶端顯示收到的消息。當(dāng)多個用戶同時(shí)使用該聊天室時(shí),每個用戶都可以看到其他用戶發(fā)送的消息。
總結(jié)
本文介紹了 Spring Boot 中的 SockJS
,包括 SockJS
的原理、使用方法和示例代碼
到此這篇關(guān)于Spring Boot 中的 SockJS的文章就介紹到這了,更多相關(guān)Spring Boot SockJS內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringCloud之@FeignClient()注解的使用詳解
@FeignClient是SpringCloud中用于聲明一個Feign客戶端的注解,用于解決模塊方法互相調(diào)用的問題,Feign是一個聲明式的WebService客戶端,通過Feign,只需要創(chuàng)建一個接口,并使用注解來描述請求,就可以直接執(zhí)行HTTP請求了2024-11-11Apache?Commons?BeanUtils:?JavaBean操作方法
這篇文章主要介紹了Apache?Commons?BeanUtils:?JavaBean操作的藝術(shù),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12- RSA解決了對稱加密的一個不足,比如AES算法加密和解密時(shí)使用的是同一個秘鑰,因此這個秘鑰不能公開,因此對于需要公開秘鑰的場合,我們需要在加密和解密過程中使用不同的秘鑰,加密使用的公鑰可以公開,解密使用的私鑰要保密,這就是非對稱加密的好處?!?/div> 2021-06-06
spring-redis-session 自定義 key 和過期時(shí)間
這篇文章主要介紹了spring-redis-session 自定義 key 和過期時(shí)間,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12最新評論