spring Boot的學習持續進行中。前面兩篇博客我們介紹了如何使用Spring Boot容器搭建Web項目以及怎樣為我們的Project添加HTTPS的支持,在這兩篇文章的基礎上,我們今天來看看如何在Spring Boot中使用WebSocket。
什么是WebSocket
WebSocket為瀏覽器和服務器之間提供了雙工異步通信功能,也就是說我們可以利用瀏覽器給服務器發送消息,服務器也可以給瀏覽器發送消息,目前主流瀏覽器的主流版本對WebSocket的支持都算是比較好的,但是在實際開發中使用WebSocket工作量會略大,而且增加了瀏覽器的兼容問題,這種時候我們更多的是使用WebSocket的一個子協議stomp,利用它來快速實現我們的功能。OK,關于WebSocket我這里就不再多說,我們主要看如何使用。
Project創建
使用WebSocket需要我們先創建一個Project,這個Project的創建方式和我們前文(初識Spring Boot框架)說的一樣,不同的是在選擇依賴的時候選擇Thymeleaf和WebSocket依賴,如下圖:
配置WebSocket
Project創建成功之后,我們先來配置WebSocket,創建如下類:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) { stompEndpointRegistry.addEndpoint( "/endpointSang" ).withSockJS(); } @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.enableSimpleBroker( "/topic" ); } } |
關于這個類我說如下幾點:
1@EnableWebSocketMessageBroker注解表示開啟使用STOMP協議來傳輸基于代理的消息,Broker就是代理的意思。
2.registerStompEndpoints方法表示注冊STOMP協議的節點,并指定映射的URL。
3.stompEndpointRegistry.addEndpoint("/endpointSang").withSockJS();這一行代碼用來注冊STOMP協議節點,同時指定使用SockJS協議。
4.configureMessageBroker方法用來配置消息代理,由于我們是實現推送功能,這里的消息代理是/topic
創建瀏覽器發送消息的接收類
瀏覽器發送來的消息用這個類來接收:
1
2
3
4
5
6
7
8
|
public class RequestMessage { private String name; public String getName() { return name; } } |
創建響應消息類
服務器返回給瀏覽器的消息由這個類來承載:
1
2
3
4
5
6
7
8
9
10
11
|
public class ResponseMessage { private String responseMessage; public ResponseMessage(String responseMessage) { this .responseMessage = responseMessage; } public String getResponseMessage() { return responseMessage; } } |
創建控制器
1
2
3
4
5
6
7
8
9
|
@Controller public class WsController { @MessageMapping ( "/welcome" ) @SendTo ( "/topic/getResponse" ) public ResponseMessage say(RequestMessage message) { System.out.println(message.getName()); return new ResponseMessage( "welcome," + message.getName() + " !" ); } } |
關于這個控制器,首先@Controller注解不必多言,say方法上添加的@MessageMapping注解和我們之前使用的@RequestMapping類似。@SendTo注解表示當服務器有消息需要推送的時候,會對訂閱了@SendTo中路徑的瀏覽器發送消息。
添加腳本
我們這個案例需要三個js腳本文件,分別是STOMP協議的客戶端腳本stomp.js、SockJS的客戶端腳本sock.js以及jQuery,這三個js文件拷貝到src/main/resources/static/js目錄下。OK,這三個js文件我已經為小伙伴們準備好了,可以直接在文末下載案例,案例中有,也可以自行下載這三個js文件。
演示頁面
在寫這個HTML頁面之前,我想先說我們要實現的效果是什么樣子的。當我的Project啟動之后,在瀏覽器訪問消息發送頁面,在該頁面發送一條消息,當服務端收到這條消息之后給所有的連接上了服務器的瀏覽器都發送一條消息。OK,我們在src/main/resources/templates目錄下新建一個ws.html頁面,內容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
<html lang= "en" xmlns:th= "http://www.thymeleaf.org" > <head> <meta charset= "UTF-8" /> <title>廣播式WebSocket</title> <script th:src= "@{js/sockjs.min.js}" ></script> <script th:src= "@{js/stomp.js}" ></script> <script th:src= "@{js/jquery-3.1.1.js}" ></script> </head> <body onload= "disconnect()" > <noscript><h2 style= "color: #e80b0a;" >Sorry,瀏覽器不支持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();" >發送</button> <p id= "response" ></p> </div> </div> <script type= "text/javascript" > var stompClient = null ; function setConnected(connected) { document.getElementById( "connect" ).disabled = connected; document.getElementById( "disconnect" ).disabled = !connected; document.getElementById( "conversationDiv" ).style.visibility = connected ? 'visible' : 'hidden' ; // $("#connect").disabled = connected; // $("#disconnect").disabled = !connected; $( "#response" ).html(); } function connect() { var socket = new SockJS( '/endpointSang' ); stompClient = Stomp.over(socket); stompClient.connect({}, function (frame) { setConnected( true ); console.log( 'Connected:' + frame); 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(); console.log( 'name:' + name); stompClient.send( "/welcome" , {}, JSON.stringify({ 'name' : name})); } function showResponse(message) { $( "#response" ).html(message); } </script> </body> </html> |
這里雖然代碼略多,但是仔細分析一下卻也很簡單。首先js文件引入的那一部分我就不再多說,這里如果又不理解的可以參考使用Spring Boot開發Web項目。然后我們的頁面上先有兩個按鈕,一個是連接,一個是斷開連接,兩個按鈕分別對應不同的點擊事件,在這兩個按鈕下方有一個輸入框,就是我們要發送的內容,然后還有一個發送按鈕,發送按鈕對應了一個發送消息的點擊事件。這是整個頁面的元素,很簡單,我們這里重點來看一下js邏輯代碼。
connect方法是當我點擊連接按鈕的時候執行的,var socket = new SockJS('/endpointSang');表示連接的SockJS的endpoint名稱為/endpointSang,stompClient = Stomp.over(socket);表示使用STOMP來創建WebSocket客戶端。然后調用stompClient中的connect方法來連接服務端,連接成功之后調用setConnected方法,該隱藏的隱藏,該顯示的顯示。然后再通過調用stompClient中的subscribe方法來訂閱/topic/getResponse發送來的消息,也就是我們在Controller中的say方法上添加的@SendTo注解的參數。stompClient中的send方法表示發送一條消息到服務端,其他的都是常規的js用法我就不再贅述。
配置viewController
接下來就是要為ws.html提供路徑映射:
1
2
3
4
5
6
7
|
@Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController( "/ws" ).setViewName( "/ws" ); } } |
OK,做完這一切之后我們就可以運行項目了,我同時打開多個瀏覽器,然后在其中一個上發送消息,我們來看看結果:
我在最上面的瀏覽器上發送消息,其他兩個瀏覽器都能收到我的消息。
OK ,以上就是我們在Spring Boot框架下使用WebSocket實現消息推送的全過程。
本案例下載地址:demo
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://blog.csdn.net/u012702547/article/details/53816326