詳解在Spring Boot框架下使用WebSocket實(shí)現(xiàn)消息推送
spring Boot的學(xué)習(xí)持續(xù)進(jìn)行中。前面兩篇博客我們介紹了如何使用Spring Boot容器搭建Web項(xiàng)目以及怎樣為我們的Project添加HTTPS的支持,在這兩篇文章的基礎(chǔ)上,我們今天來看看如何在Spring Boot中使用WebSocket。
什么是WebSocket
WebSocket為瀏覽器和服務(wù)器之間提供了雙工異步通信功能,也就是說我們可以利用瀏覽器給服務(wù)器發(fā)送消息,服務(wù)器也可以給瀏覽器發(fā)送消息,目前主流瀏覽器的主流版本對WebSocket的支持都算是比較好的,但是在實(shí)際開發(fā)中使用WebSocket工作量會(huì)略大,而且增加了瀏覽器的兼容問題,這種時(shí)候我們更多的是使用WebSocket的一個(gè)子協(xié)議stomp,利用它來快速實(shí)現(xiàn)我們的功能。OK,關(guān)于WebSocket我這里就不再多說,我們主要看如何使用。
Project創(chuàng)建
使用WebSocket需要我們先創(chuàng)建一個(gè)Project,這個(gè)Project的創(chuàng)建方式和我們前文(初識Spring Boot框架)說的一樣,不同的是在選擇依賴的時(shí)候選擇Thymeleaf和WebSocket依賴,如下圖:
配置WebSocket
Project創(chuàng)建成功之后,我們先來配置WebSocket,創(chuàng)建如下類:
@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"); } }
關(guān)于這個(gè)類我說如下幾點(diǎn):
1@EnableWebSocketMessageBroker注解表示開啟使用STOMP協(xié)議來傳輸基于代理的消息,Broker就是代理的意思。
2.registerStompEndpoints方法表示注冊STOMP協(xié)議的節(jié)點(diǎn),并指定映射的URL。
3.stompEndpointRegistry.addEndpoint("/endpointSang").withSockJS();這一行代碼用來注冊STOMP協(xié)議節(jié)點(diǎn),同時(shí)指定使用SockJS協(xié)議。
4.configureMessageBroker方法用來配置消息代理,由于我們是實(shí)現(xiàn)推送功能,這里的消息代理是/topic
創(chuàng)建瀏覽器發(fā)送消息的接收類
瀏覽器發(fā)送來的消息用這個(gè)類來接收:
public class RequestMessage { private String name; public String getName() { return name; } }
創(chuàng)建響應(yīng)消息類
服務(wù)器返回給瀏覽器的消息由這個(gè)類來承載:
public class ResponseMessage { private String responseMessage; public ResponseMessage(String responseMessage) { this.responseMessage = responseMessage; } public String getResponseMessage() { return responseMessage; } }
創(chuàng)建控制器
@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() + " !"); } }
關(guān)于這個(gè)控制器,首先@Controller注解不必多言,say方法上添加的@MessageMapping注解和我們之前使用的@RequestMapping類似。@SendTo注解表示當(dāng)服務(wù)器有消息需要推送的時(shí)候,會(huì)對訂閱了@SendTo中路徑的瀏覽器發(fā)送消息。
添加腳本
我們這個(gè)案例需要三個(gè)js腳本文件,分別是STOMP協(xié)議的客戶端腳本stomp.js、SockJS的客戶端腳本sock.js以及jQuery,這三個(gè)js文件拷貝到src/main/resources/static/js目錄下。OK,這三個(gè)js文件我已經(jīng)為小伙伴們準(zhǔn)備好了,可以直接在文末下載案例,案例中有,也可以自行下載這三個(gè)js文件。
演示頁面
在寫這個(gè)HTML頁面之前,我想先說我們要實(shí)現(xiàn)的效果是什么樣子的。當(dāng)我的Project啟動(dòng)之后,在瀏覽器訪問消息發(fā)送頁面,在該頁面發(fā)送一條消息,當(dāng)服務(wù)端收到這條消息之后給所有的連接上了服務(wù)器的瀏覽器都發(fā)送一條消息。OK,我們在src/main/resources/templates目錄下新建一個(gè)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>
這里雖然代碼略多,但是仔細(xì)分析一下卻也很簡單。首先js文件引入的那一部分我就不再多說,這里如果又不理解的可以參考使用Spring Boot開發(fā)Web項(xiàng)目。然后我們的頁面上先有兩個(gè)按鈕,一個(gè)是連接,一個(gè)是斷開連接,兩個(gè)按鈕分別對應(yīng)不同的點(diǎn)擊事件,在這兩個(gè)按鈕下方有一個(gè)輸入框,就是我們要發(fā)送的內(nèi)容,然后還有一個(gè)發(fā)送按鈕,發(fā)送按鈕對應(yīng)了一個(gè)發(fā)送消息的點(diǎn)擊事件。這是整個(gè)頁面的元素,很簡單,我們這里重點(diǎn)來看一下js邏輯代碼。
connect方法是當(dāng)我點(diǎn)擊連接按鈕的時(shí)候執(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提供路徑映射:
@Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/ws").setViewName("/ws"); } }
OK,做完這一切之后我們就可以運(yùn)行項(xiàng)目了,我同時(shí)打開多個(gè)瀏覽器,然后在其中一個(gè)上發(fā)送消息,我們來看看結(jié)果:
我在最上面的瀏覽器上發(fā)送消息,其他兩個(gè)瀏覽器都能收到我的消息。
OK ,以上就是我們在Spring Boot框架下使用WebSocket實(shí)現(xiàn)消息推送的全過程。
本案例下載地址:demo
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
IDEA搭建配置Java?Web項(xiàng)目的詳細(xì)步驟
這篇文章詳細(xì)介紹了如何使用IDEA創(chuàng)建和配置JavaWeb項(xiàng)目,包括項(xiàng)目結(jié)構(gòu)設(shè)置、WEB-INF目錄和jsp文件的創(chuàng)建,以及Tomcat的配置,是Java初學(xué)者的實(shí)用指南,需要的朋友可以參考下2024-10-10SpringMVC實(shí)現(xiàn)Controller的三種方式總結(jié)
這篇文章主要介紹了SpringMVC實(shí)現(xiàn)Controller的三種方式總結(jié),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02SpringBoot配置 Druid 三種方式(包括純配置文件配置)
本文給大家分享在項(xiàng)目中用純 YML(application.yml 或者 application.properties)文件、Java 代碼配置 Bean 和注解三種方式配置 Alibaba Druid 用于監(jiān)控或者查看 SQL 狀況的相關(guān)知識,感興趣的朋友一起看看吧2021-10-10java abstract class interface之間的區(qū)別介紹
含有abstract修飾符的class即為抽象類,abstract 類不能創(chuàng)建的實(shí)例對象,abstract class類中定義抽象方法必須在具體(Concrete)子類中實(shí)現(xiàn),所以,不能有抽象構(gòu)造方法或抽象靜態(tài)方法2012-11-11Java動(dòng)態(tài)線程池插件dynamic-tp集成zookeeper
ZooKeeper是一個(gè)分布式的,開放源碼的分布式應(yīng)用程序協(xié)調(diào)服務(wù),是Google的Chubby一個(gè)開源的實(shí)現(xiàn),是Hadoop和Hbase的重要組件。它是一個(gè)為分布式應(yīng)用提供一致性的軟件,提供的功能包括:配置維護(hù)、域名服務(wù)、分布式同步、組服務(wù)等2023-03-03SpringBoot2.X Kotlin系列之?dāng)?shù)據(jù)校驗(yàn)和異常處理詳解
這篇文章主要介紹了SpringBoot 2.X Kotlin系列之?dāng)?shù)據(jù)校驗(yàn)和異常處理詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-04-04@ConfigurationProperties綁定配置信息至Array、List、Map、Bean的實(shí)現(xiàn)
這篇文章主要介紹了@ConfigurationProperties綁定配置信息至Array、List、Map、Bean的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05springboot項(xiàng)目如何設(shè)置session的過期時(shí)間
這篇文章主要介紹了springboot項(xiàng)目如何設(shè)置session的過期時(shí)間,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01使用lombok注解導(dǎo)致mybatis-plus TypeHandler失效的解決
這篇文章主要介紹了使用lombok注解導(dǎo)致mybatis-plus TypeHandler失效的解決,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07