亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

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

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

瀏覽:25日期: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://www.aoyou183.cn/webjars/bootstrap/css/bootstrap.min.css' rel='external nofollow' rel='stylesheet'> <link href='http://www.aoyou183.cn/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
相關文章:
主站蜘蛛池模板: 国产精品亚洲专区在线观看 | a久久久久一级毛片护士免费 | 亚洲欧美日韩高清一区二区一 | 亚洲精品一二三四区 | 两个人看的www视频中文字幕 | 国产一区二区视频在线播放 | 九月丁香婷婷 | 国产91成人精品亚洲精品 | 1024你懂的国产欧美日韩在 | 日韩精品一区二区三区四区 | 久久精品福利视频在线观看 | 成人三级在线 | 在线观看香蕉免费啪在线观看 | 国产精品黄页网站在线播放免费 | 国产精品亚洲专区在线播放 | 国产成人99精品免费观看 | 视频成人永久免费视频 | 欧美一级大片免费看 | 久久福利一区 | 成人亚洲国产精品久久 | 国产成人精品男人的天堂538 | 一级毛片免费观看视频 | 亚州综合 | 女视频www女中国 | 久久亚洲精品成人综合 | 18在线网站| 成人精品美女隐私漫画 | 九九啪| 一级午夜a毛片免费视频 | 亚洲妇熟xxxx妇色黄 | 国产精品视频一区麻豆 | 能免费观看的韩剧 | 免费香蕉一区二区在线观看 | 日本特黄色大片 | 国内精品在线观看视频 | 欧美一级毛片图 | 亚洲国产精品一区二区久 | 日韩色视频一区二区三区亚洲 | 日本老太婆一级毛片免费 | 97国产大学生情侣11在线视频 | 风间由美理论片在线观看 |