日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

SpringBoot+STOMP協議實現私聊、群聊

瀏覽:108日期:2023-03-05 14:11:28
目錄一、為什么需要STOMP?二、STOMP詳解三、SpringBoot集成STOMP代碼示例3.1、功能示例3.2、架構圖3.3、服務端代碼3.4、h5代碼一、為什么需要STOMP?

WebSocket 協議是一種相當低級的協議。它定義了如何將字節流轉換為幀。幀可以包含文本或二進制消息。由于消息本身不提供有關如何路由或處理它的任何其他信息,因此很難在不編寫其他代碼的情況下實現更復雜的應用程序。幸運的是,WebSocket 規范允許在更高的應用程序級別上使用子協議。

另外,單單使用WebSocket完成群聊、私聊功能時,需要自己管理session信息,通過STOMP協議時,spring已經封裝好,開發者只需要關注自己的主題、訂閱關系即可。

二、STOMP詳解

SpringBoot+STOMP協議實現私聊、群聊

STOMP 中文為“面向消息的簡單文本協議”,STOMP 提供了能夠協作的報文格式,以至于 STOMP 客戶端可以與任何 STOMP 消息代理(Brokers)進行通信,從而為多語言,多平臺和 Brokers 集群提供簡單且普遍的消息協作。STOMP 協議可以建立在 WebSocket 之上,也可以建立在其他應用層協議之上。通過 Websocket建立 STOMP 連接,也就是說在 Websocket 連接的基礎上再建立 STOMP 連接。最終實現如上圖所示,這一點可以在代碼中有一個良好的體現。

業界已經有很多優秀的 STOMP 的服務器/客戶端的開源實現

STOMP 服務器:ActiveMQ、RabbitMQ、StompServer、… STOMP 客戶端庫:stomp.js(javascript)

Stomp 的特點是客戶端的實現很容易,服務端相當于消息隊列的 broker 或者是 server,一般不需要我們去實現,所以重點關注一下客戶端如何使用

CONNECT 啟動與服務器的流或 TCP 連接 SEND發送消息 SUBSCRIBE 訂閱主題 UNSUBSCRIBE 取消訂閱 BEGIN 啟動事物 COMMIT提交事物 ABORT回滾事物 ACK確認來自訂閱的消息的消費 NACK告訴服務器客戶端沒有消費該消息 DISCONNECT斷開連接

其實STOMP協議并不是為WS所設計的, 它其實是消息隊列的一種協議, 和AMQP,JMS是平級的。 只不過由于它的簡單性恰巧可以用于定義WS的消息體格式。 目前很多服務端消息隊列都已經支持了STOMP, 比如RabbitMQ, Apache ActiveMQ等。很多語言也都有STOMP協議的客戶端解析庫,像JAVA的Gozirra,C的libstomp,Python的pyactivemq,JavaScript的stomp.js等等。

STOMP協議官方文檔

三、SpringBoot集成STOMP代碼示例3.1、功能示例

SpringBoot+STOMP協議實現私聊、群聊

SpringBoot+STOMP協議實現私聊、群聊

3.2、架構圖

SpringBoot+STOMP協議實現私聊、群聊

3.3、服務端代碼

pom文件引入jar

<?xml version='1.0' encoding='UTF-8'?><project xmlns='http://maven.apache.org/POM/4.0.0' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd'> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>websocket-demo</artifactId> <version>1.0-SNAPSHOT</version> <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.10.RELEASE</version><relativePath/> <!-- lookup parent from repository --> </parent> <properties><java.version>1.8</java.version> </properties> <dependencies><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency><dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId></dependency><dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version></dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId></dependency><dependency> <groupId>org.webjars</groupId> <artifactId>webjars-locator-core</artifactId></dependency><dependency> <groupId>org.webjars</groupId> <artifactId>sockjs-client</artifactId> <version>1.0.2</version></dependency><dependency> <groupId>org.webjars</groupId> <artifactId>stomp-websocket</artifactId> <version>2.3.3</version></dependency><dependency> <groupId>org.webjars</groupId> <artifactId>bootstrap</artifactId> <version>3.3.7</version></dependency><dependency> <groupId>org.webjars</groupId> <artifactId>jquery</artifactId> <version>3.1.0</version></dependency><dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.62</version></dependency> </dependencies> <build><plugins> <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration> <source>1.8</source> <target>1.8</target></configuration> </plugin></plugins> </build></project>

WebSocketMessageBroker配置類

@Configuration@EnableWebSocketMessageBrokerpublic class WebSocketConfig implements WebSocketMessageBrokerConfigurer{// 啟用一個簡單的基于內存的消息代理@Overridepublic void configureMessageBroker(MessageBrokerRegistry config) {//通過/topic 開頭的主題可以進行訂閱config.enableSimpleBroker('/topic');//send命令時需要帶上/app前綴config.setApplicationDestinationPrefixes('/app');//修改convertAndSendToUser方法前綴, 稍后解釋作用//config.setUserDestinationPrefix ('/myUserPrefix');}@Overridepublic void registerStompEndpoints(StompEndpointRegistry registry) {//連接前綴registry.addEndpoint('/gs-guide-websocket').setAllowedOrigins('*') // 跨域處理.withSockJS(); //支持socketJs}}

@EnableWebSocketMessageBroker注解啟用 WebSocket 消息處理,由消息代理支持。

SockJS 有一些瀏覽器中缺少對 WebSocket 的支持,而 SockJS 是一個瀏覽器的 JavaScript庫,它提供了一個類似于網絡的對象,SockJS 提供了一個連貫的,跨瀏覽器的JavaScriptAPI,它在瀏覽器和 Web 服務器之間創建了一個低延遲、全雙工、跨域通信通道。SockJS 的一大好處在于提供了瀏覽器兼容性。即優先使用原生WebSocket,如果瀏覽器不支持 WebSocket,會自動降為輪詢的方式。如果你使用 Java 做服務端,同時又恰好使用 Spring Framework 作為框架,那么推薦使用SockJS。

控制器代碼

@Slf4j@RestControllerpublic class TestController{@Autowiredprivate SimpMessagingTemplate simpMessagingTemplate;@MessageMapping('/hello')@SendTo ('/topic/greetings')public Greeting greeting(HelloMessage message) throws Exception {Thread.sleep(1000); // simulated delayreturn new Greeting('Hello, ' + HtmlUtils.htmlEscape(message.getName()) + '!');}@MessageMapping('/topic/greetings')public Greeting greeting2(HelloMessage message) throws Exception {Thread.sleep(1000); // simulated delaylog.info ('Hello, ' + HtmlUtils.htmlEscape(message.getName()) + '!');return new Greeting('Hello, ' + HtmlUtils.htmlEscape(message.getName()) + '!');}@GetMapping ('/hello2')public void greeting3(HelloMessage message) throws Exception {Thread.sleep(1000); // simulated delaysimpMessagingTemplate.convertAndSend ('/topic/greetings',new Greeting('Hello, ' + HtmlUtils.htmlEscape(message.getName()) + '!'));}@MessageMapping('/sendToUser')public void sendToUser(HelloMessage message) throws Exception {Thread.sleep(1000); // simulated delaylog.info ('userId:{},msg:{}',message.getUserId (),message.getName ());//simpMessagingTemplate.convertAndSendToUser (message.getUserId (),'/sendToUser',//new Greeting('Hello, ' + HtmlUtils.htmlEscape(message.getName()) + '!'));//simpMessagingTemplate.convertAndSend ('/user/1/sendToUser',//new Greeting('Hello, ' + HtmlUtils.htmlEscape(message.getName()) + '!'));simpMessagingTemplate.convertAndSend ('/topic/user/'+message.getUserId ()+'/sendToUser',new Greeting('Hello, ' + HtmlUtils.htmlEscape(message.getName()) + '!'));}} @MessageMapping 功能與RequestMapping注解類似。send指令發送信息時添加此注解 @SendTo/@SendToUser 將信息輸出到該主題。客戶端訂閱同樣的主題后就會收到信息。 在只有指定@MessageMapping時@MessageMapping == “/topic” + @SendTo 如果想使用rest接口發送消息。可以通過SimpMessagingTemplate進行發送。 點對點聊天時,可以使用SimpMessagingTemplate.convertAndSendToUser方法發送。個人意味比注解@SendToUser更加容易理解,更加方便 convertAndSendToUser方法和convertAndSend類似,區別在于convertAndSendToUser方法會在主題默認添加/user/為前綴。因此,示例代碼中convertAndSend方法直接傳入'/topic/user/'+message.getUserId ()+'/sendToUser' 也是點對點發送。topic其中是默認前綴。 如果想修改convertAndSendToUser默認前綴可在配置類進行配置,可在WebSocketConfig類中查看。3.4、h5代碼

<!DOCTYPE html><html><head> <title>Hello WebSocket</title> <link href='http://m.b3g6.com/webjars/bootstrap/css/bootstrap.min.css' rel='external nofollow' rel='stylesheet'> <link href='http://m.b3g6.com/main.css' rel='external nofollow' rel='stylesheet'> <script type='text/javascript' src='https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js'></script> <script src='https://rkxy.com.cn/webjars/sockjs-client/sockjs.min.js'></script> <script src='https://rkxy.com.cn/webjars/stomp-websocket/stomp.min.js'></script> <script src='https://rkxy.com.cn/app.js'></script></head><body><noscript><h2 style='color: #ff0000'>Seems your browser doesn’t support Javascript! Websocket relies on Javascript being enabled. Please enable Javascript and reload this page!</h2></noscript><div class='container'> <div class='row'><div class='col-md-6'> <form class='form-inline'><div class='form-group'> <label for='connect'>WebSocket connection:</label> <button type='submit'>Connect</button> <button type='submit' disabled='disabled'>Disconnect </button></div> </form></div><div class='col-md-6'> <form class='form-inline'><div class='form-group'> <label for='name'>What is your name?</label> <input type='text' placeholder='Your name here...'> <input type='text' placeholder='userId'></div><button type='submit'>Send</button><button type='submit'>Send2</button><button type='submit'>SendToUser</button> </form></div> </div> <div class='row'><div class='col-md-12'> <table class='table table-striped'><thead><tr> <th>Greetings</th></tr></thead><tbody id='greetings'></tbody> </table></div> </div></div></body></html>

app.js

var stompClient = null;var userId = null;function setConnected(connected) { $('#connect').prop('disabled', connected); $('#disconnect').prop('disabled', !connected); if (connected) {$('#conversation').show(); } else {$('#conversation').hide(); } $('#greetings').html('');}function connect() { var socket = new SockJS(’/gs-guide-websocket’); stompClient = Stomp.over(socket); stompClient.connect({}, function (frame) {setConnected(true);console.log(’Connected: ’ + frame);stompClient.subscribe(’/topic/greetings’, function (greeting) { showGreeting(JSON.parse(greeting.body).content);});//對應controller greeting2方法 注意,這兒有兩個topic stompClient.subscribe(’/topic/topic/greetings’, function (greeting) {showGreeting(JSON.parse(greeting.body).content); }); stompClient.subscribe(’/topic/user/’+userId+’/sendToUser’, function (greeting) { showGreeting(JSON.parse(greeting.body).content); }); stompClient.subscribe(’/user/’+userId+’/sendToUser’, function (greeting) { showGreeting(JSON.parse(greeting.body).content); }); });}function disconnect() { if (stompClient !== null) {stompClient.disconnect(); } setConnected(false); console.log('Disconnected');}function sendName() { stompClient.send('/app/hello', {}, JSON.stringify({’name’: $('#name').val()}));// stompClient.send('/hello', {}, JSON.stringify({’name’: $('#name').val()}));}function sendName2() { stompClient.send('/app/topic/greetings', {}, JSON.stringify({’name’: $('#name').val()}));// stompClient.send('/topic/greetings', {}, JSON.stringify({’name’: $('#name').val()}));}function sendName3() { stompClient.send('/app/sendToUser', {}, JSON.stringify({’userId’:$('#userId').val(),’name’: $('#name').val()}));}function showGreeting(message) { $('#greetings').append('<tr><td>' + message + '</td></tr>');}function GetQueryString(name) {var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');var r = window.location.search.substr(1).match(reg); //獲取url中'?'符后的字符串并正則匹配var context = '';if (r != null)context = r[2];reg = null;r = null;return context == null || context == '' || context == 'undefined' ? '' : context;}$(function () { userId = GetQueryString('userId'); $('form').on(’submit’, function (e) {e.preventDefault(); }); $( '#connect' ).click(function() { connect(); }); $( '#disconnect' ).click(function() { disconnect(); }); $( '#send' ).click(function() { sendName(); }); $( '#send2' ).click(function() { sendName2(); }); $( '#send3' ).click(function() { sendName3(); });});

一些無關緊要的類

public class Greeting{ private String content; public Greeting() { } public Greeting(String content) { this.content = content; } public String getContent() { return content; }}

public class HelloMessage{ private String userId; private String name; // 省去get/set}Name3(); });});

spring參考文檔

websocket參考文檔

到此這篇關于SpringBoot+STOMP協議實現私聊、群聊的文章就介紹到這了,更多相關SpringBoot STOMP私聊、群聊內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Spring
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
中文不卡在线| 色一区二区三区| 日本成人在线一区| 久久精品毛片| 五月天久久777| 欧美午夜三级| 亚洲精品日本| 国产精品一区二区av日韩在线| 影音国产精品| 91精品一区二区三区综合| 国产精品九九| 欧美久久亚洲| 偷拍亚洲精品| 青青草国产成人99久久| 免费一区二区视频| 97精品国产| 欧美国产不卡| 精品日产乱码久久久久久仙踪林| 日本中文字幕不卡| 在线精品视频一区| 亚洲成人免费| 激情自拍一区| 青草综合视频| 国产精品66| 国产无遮挡裸体免费久久| 911亚洲精品| 蜜臀久久久99精品久久久久久| 在线观看视频免费一区二区三区| 欧美国产日韩电影| 午夜国产一区二区| 黄色不卡一区| 91成人精品观看| 激情黄产视频在线免费观看| 午夜精品免费| 亚洲午夜久久| 国产欧美在线| 免费在线亚洲欧美| 亚洲国产日韩欧美在线| 在线精品国产亚洲| 日本不卡一区二区| 蜜臀av在线播放一区二区三区| 日韩精品一二三| 蜜桃久久久久久久| 亚洲精品影院在线观看| 亚洲免费黄色| 日韩在线卡一卡二| 国产精品99一区二区| 水野朝阳av一区二区三区| 亚洲精品美女91| 欧美国产日韩电影| 欧美日韩四区| 麻豆一区二区99久久久久| 欧美在线观看视频一区| 日韩精品高清不卡| 久久精品播放| 91在线成人| 久久精品av| 国产精品极品| 激情偷拍久久| 国产精品xxxav免费视频| 国产综合亚洲精品一区二| 亚洲免费观看高清完整版在线观| 超级白嫩亚洲国产第一| 在线精品观看| 日韩在线短视频| 日韩国产一二三区| 日韩一区二区三区免费| 欧美精品国产白浆久久久久| 国产一区二区三区自拍| 国产精品sss在线观看av| 国产美女精品| 国产精品亚洲一区二区三区在线观看| 在线精品亚洲| 九九色在线视频| 国产精品一页| 欧美特黄一区| 久久久久亚洲精品中文字幕| 蜜桃视频一区二区| 欧美aa在线观看| 国产精品伦一区二区| 香蕉久久久久久久av网站| 国产自产自拍视频在线观看| 欧美日韩一区二区国产 | 妖精视频成人观看www| 在线视频亚洲| 亚洲综合激情在线| 欧美日韩精品在线一区| 蜜桃久久av| 欧美激情三区| 欧美亚洲tv| 日韩三级精品| 欧美另类专区| 在线看片福利| 精品一区二区三区亚洲 | a日韩av网址| 国产欧美亚洲一区| 综合激情视频| 夜夜嗨av一区二区三区网站四季av| 久久精品一本| 国产精品亚洲产品| 日韩精品第二页| 男女性色大片免费观看一区二区| 人人精品亚洲| 成人污污视频| 麻豆精品视频在线观看视频| 国产欧美一区二区精品久久久| 亚洲精品第一| 亚洲综合福利| 男女男精品视频网| 亚洲综合电影一区二区三区| 在线精品小视频| 亚洲精品观看| 视频一区二区三区入口| 日韩精品一区二区三区免费观影 | 在线天堂资源www在线污| 西西人体一区二区| 97久久中文字幕| 亚洲主播在线| 久久午夜精品一区二区| 国产乱论精品| 亚洲国产一区二区在线观看 | 日韩中文字幕区一区有砖一区| 美女久久网站| 亚洲激情久久| 九九久久婷婷| 天堂网av成人| 夜久久久久久| 日韩福利视频一区| 青青草视频一区| 国产伦理久久久久久妇女| 日本高清久久| 精品网站999| 日韩欧美一区二区三区免费观看| 影音国产精品| 国产亚洲一区二区三区不卡| 国产精品中文字幕制服诱惑| 欧美在线亚洲| 欧美~级网站不卡| 免费观看在线色综合| 红杏一区二区三区| 日韩国产专区| 日韩福利一区| 亚洲午夜电影| 亚洲激情中文| 日韩一区二区三区免费视频| 日韩在线高清| 香蕉久久精品| 亚洲免费影院| 三级久久三级久久久| 国产精品毛片久久久| 中文字幕高清在线播放| 精品一区在线| 日韩精品免费一区二区夜夜嗨| 国产探花一区在线观看| 国产v日韩v欧美v| 日韩欧美精品一区| **爰片久久毛片| 日韩av首页| 国产人成精品一区二区三| 国产精品毛片在线| 久久久久亚洲| 日韩一区中文| 日韩欧美三级| 国产精品网址| 91久久黄色| 精品日韩视频| 日韩电影二区| 99久久精品国产亚洲精品| 国产色99精品9i| 日韩欧美2区| 日韩精品午夜视频| 亚洲精品人人| 一区二区电影在线观看| 欧美/亚洲一区| 999久久久91| 美女高潮久久久| 国产精品magnet| 91精品韩国| 婷婷综合一区| 丝袜美腿亚洲一区| 婷婷综合网站| 在线一区电影| 国产探花一区二区| 国产欧美精品久久| 欧美综合精品| 欧美专区18| 91精品在线免费视频| 久久影院一区二区三区| 久久激情中文| 日韩美女国产精品| 久久亚洲黄色| 久久国产精品亚洲77777| 久久天堂影院| 爽好多水快深点欧美视频| 精品久久影院| 久久精品国语| 国产精品99一区二区| 亚洲在线免费| 国产精选一区| 亚洲精品一二|