spring Boot的學(xué)習(xí)持續(xù)進行中。前面兩篇博客我們介紹了如何使用Spring Boot容器搭建Web項目以及怎樣為我們的Project添加HTTPS的支持,在這兩篇文章的基礎(chǔ)上,我們今天來看看如何在Spring Boot中使用WebSocket。
什么是WebSocket
WebSocket為瀏覽器和服務(wù)器之間提供了雙工異步通信功能,也就是說我們可以利用瀏覽器給服務(wù)器發(fā)送消息,服務(wù)器也可以給瀏覽器發(fā)送消息,目前主流瀏覽器的主流版本對WebSocket的支持都算是比較好的,但是在實際開發(fā)中使用WebSocket工作量會略大,而且增加了瀏覽器的兼容問題,這種時候我們更多的是使用WebSocket的一個子協(xié)議stomp,利用它來快速實現(xiàn)我們的功能。OK,關(guān)于WebSocket我這里就不再多說,我們主要看如何使用。
Project創(chuàng)建
使用WebSocket需要我們先創(chuàng)建一個Project,這個Project的創(chuàng)建方式和我們前文(初識Spring Boot框架)說的一樣,不同的是在選擇依賴的時候選擇Thymeleaf和WebSocket依賴,如下圖: 

配置WebSocket
Project創(chuàng)建成功之后,我們先來配置WebSocket,創(chuàng)建如下類:
@Configuration@EnableWebSocketMessageBrokerpublic class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {  @Override  public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {    stompEndpointRegistry.addEndpoint("/endpointSang").withSockJS();  }  @Override  public void configureMessageBroker(MessageBrokerRegistry registry) {    registry.enableSimpleBroker("/topic");  }}關(guān)于這個類我說如下幾點:
1@EnableWebSocketMessageBroker注解表示開啟使用STOMP協(xié)議來傳輸基于代理的消息,Broker就是代理的意思。 
2.registerStompEndpoints方法表示注冊STOMP協(xié)議的節(jié)點,并指定映射的URL。 
3.stompEndpointRegistry.addEndpoint("/endpointSang").withSockJS();這一行代碼用來注冊STOMP協(xié)議節(jié)點,同時指定使用SockJS協(xié)議。 
4.configureMessageBroker方法用來配置消息代理,由于我們是實現(xiàn)推送功能,這里的消息代理是/topic
創(chuàng)建瀏覽器發(fā)送消息的接收類
瀏覽器發(fā)送來的消息用這個類來接收:
public class RequestMessage {  private String name;  public String getName() {    return name;  }}創(chuàng)建響應(yīng)消息類
服務(wù)器返回給瀏覽器的消息由這個類來承載:
public class ResponseMessage {  private String responseMessage;  public ResponseMessage(String responseMessage) {    this.responseMessage = responseMessage;  }  public String getResponseMessage() {    return responseMessage;  }}創(chuàng)建控制器
@Controllerpublic class WsController {  @MessageMapping("/welcome")  @SendTo("/topic/getResponse")  public ResponseMessage say(RequestMessage message) {    System.out.println(message.getName());    return new ResponseMessage("welcome," + message.getName() + " !");  }}關(guān)于這個控制器,首先@Controller注解不必多言,say方法上添加的@MessageMapping注解和我們之前使用的@RequestMapping類似。@SendTo注解表示當(dāng)服務(wù)器有消息需要推送的時候,會對訂閱了@SendTo中路徑的瀏覽器發(fā)送消息。
添加腳本
我們這個案例需要三個js腳本文件,分別是STOMP協(xié)議的客戶端腳本stomp.js、SockJS的客戶端腳本sock.js以及jQuery,這三個js文件拷貝到src/main/resources/static/js目錄下。OK,這三個js文件我已經(jīng)為小伙伴們準備好了,可以直接在文末下載案例,案例中有,也可以自行下載這三個js文件。
演示頁面
在寫這個HTML頁面之前,我想先說我們要實現(xiàn)的效果是什么樣子的。當(dāng)我的Project啟動之后,在瀏覽器訪問消息發(fā)送頁面,在該頁面發(fā)送一條消息,當(dāng)服務(wù)端收到這條消息之后給所有的連接上了服務(wù)器的瀏覽器都發(fā)送一條消息。OK,我們在src/main/resources/templates目錄下新建一個ws.html頁面,內(nèi)容如下:
<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();">發(fā)送</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開發(fā)Web項目。然后我們的頁面上先有兩個按鈕,一個是連接,一個是斷開連接,兩個按鈕分別對應(yīng)不同的點擊事件,在這兩個按鈕下方有一個輸入框,就是我們要發(fā)送的內(nèi)容,然后還有一個發(fā)送按鈕,發(fā)送按鈕對應(yīng)了一個發(fā)送消息的點擊事件。這是整個頁面的元素,很簡單,我們這里重點來看一下js邏輯代碼。
connect方法是當(dāng)我點擊連接按鈕的時候執(zhí)行的,var socket = new SockJS('/endpointSang');表示連接的SockJS的endpoint名稱為/endpointSang,stompClient = Stomp.over(socket);表示使用STOMP來創(chuàng)建WebSocket客戶端。然后調(diào)用stompClient中的connect方法來連接服務(wù)端,連接成功之后調(diào)用setConnected方法,該隱藏的隱藏,該顯示的顯示。然后再通過調(diào)用stompClient中的subscribe方法來訂閱/topic/getResponse發(fā)送來的消息,也就是我們在Controller中的say方法上添加的@SendTo注解的參數(shù)。stompClient中的send方法表示發(fā)送一條消息到服務(wù)端,其他的都是常規(guī)的js用法我就不再贅述。
配置viewController
接下來就是要為ws.html提供路徑映射:
@Configurationpublic class WebMvcConfig extends WebMvcConfigurerAdapter {  @Override  public void addViewControllers(ViewControllerRegistry registry) {    registry.addViewController("/ws").setViewName("/ws");  }}OK,做完這一切之后我們就可以運行項目了,我同時打開多個瀏覽器,然后在其中一個上發(fā)送消息,我們來看看結(jié)果:

我在最上面的瀏覽器上發(fā)送消息,其他兩個瀏覽器都能收到我的消息。
OK ,以上就是我們在Spring Boot框架下使用WebSocket實現(xiàn)消息推送的全過程。
本案例下載地址:demo
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。
新聞熱點
疑難解答