Springboot 整合 WebSocket ,利用STOMP协议 ,前后端整合实战 (一)

闲聊 闲聊 1453 人阅读 | 0 人回复

<
序言



websocket ,关于我来讲曾经是老伴侣了。 

 好久好久从前,我写过两篇websocket 相关的文章。


  一篇极简风,最最最根底的方法整开websocket :
  《SpringBoot 整开WebSocket 简朴真战案例》

  地点: https://blog.csdn.net/qq_35387940/article/details/93483678
一篇极限风,最最最完美的方法整开websocket (stomp+rabbitmq处理背载):
   《Springboot 整开Websocket,Stomp和谈,操纵rabbitmq做动静代办署理,动静缓存
   地点: https://blog.csdn.net/qq_35387940/article/details/108276136

可是根据近来看民们给我反响状况去看, 一个极简没有契合需供,由于看民们固然念简朴,可是也念用stomp。

但是那个极限的呢,又太庞大,看民们没有愿意来整开rabbitmq。

那末,那篇文章的意义便出去了。
 




注释


本篇内乱容:

1.后端整开websocket (STOMP和谈)
2.群收、指订单收
3.前端简朴页里示例(吸取、收收动静)

当务之急,开端敲代码。

先看下此次真战案例项目构造:

150023iehn4hllzlkekhl4.jpg


1. pom.xml 中心依靠的导进:
 
  1.     <dependencies>
  2.         <dependency>
  3.             <groupId>org.springframework.boot</groupId>
  4.             <artifactId>spring-boot-starter-websocket</artifactId>
  5.         </dependency>
  6.         <dependency>
  7.             <groupId>org.springframework.boot</groupId>
  8.             <artifactId>spring-boot-starter</artifactId>
  9.         </dependency>
  10.         <dependency>
  11.             <groupId>org.springframework.boot</groupId>
  12.             <artifactId>spring-boot-starter-test</artifactId>
  13.             <scope>test</scope>
  14.         </dependency>
  15.     </dependencies>
复造代码

2.application.yml  (我便纯真设置一下端心)
 
  1. server:
  2.   port: 9908
复造代码
3.WebSocketConfig.java
  1. import org.springframework.context.annotation.Configuration;
  2. import org.springframework.messaging.simp.config.MessageBrokerRegistry;
  3. import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
  4. import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
  5. import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
  6. /**
  7. * @Author JCccc
  8. * @Description   EnableWebSocketMessageBroker-注解开启STOMP和谈去传输基于代办署理的动静,此时掌握器撑持利用@MessageMapping
  9. * @Date 2021/6/30 8:53
  10. */
  11. @Configuration
  12. @EnableWebSocketMessageBroker
  13. public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
  14.     @Override
  15.     public void configureMessageBroker(MessageBrokerRegistry config) {
  16.         //topic用去播送,user用去完成面对面
  17.         config.enableSimpleBroker("/topic", "/user");
  18.     }
  19.     /**
  20.      * 开放节面
  21.      * @param registry
  22.      */
  23.     @Override
  24.     public void registerStompEndpoints(StompEndpointRegistry registry) {
  25.         //注册两个STOMP的endpoint,别离用于播送战面对面
  26.         //播送
  27.         registry.addEndpoint("/publicServer").withSockJS();
  28.         //面对面
  29.         registry.addEndpoint("/privateServer").withSockJS();
  30.     }
  31. }
复造代码

4.推收动静的真体类 Message.java
  1. /**
  2. * @Author JCccc
  3. * @Description
  4. * @Date 2021/8/20 9:26
  5. */
  6. public class Message {
  7.     /**
  8.      * 动静编码
  9.      */
  10.     private String code;
  11.     /**
  12.      * 去自(包管独一)
  13.      */
  14.     private String form;
  15.     /**
  16.      * 来自(包管独一)
  17.      */
  18.     private String to;
  19.     /**
  20.      * 内乱容
  21.      */
  22.     private String content;
  23.     public String getCode() {
  24.         return code;
  25.     }
  26.     public void setCode(String code) {
  27.         this.code = code;
  28.     }
  29.     public String getForm() {
  30.         return form;
  31.     }
  32.     public void setForm(String form) {
  33.         this.form = form;
  34.     }
  35.     public String getTo() {
  36.         return to;
  37.     }
  38.     public void setTo(String to) {
  39.         this.to = to;
  40.     }
  41.     public String getContent() {
  42.         return content;
  43.     }
  44.     public void setContent(String content) {
  45.         this.content = content;
  46.     }
  47. }
复造代码
5.前端简朴调试页里 
① publicExample.html 监听播送动静的测试页里
  1. <html>
  2. <head>
  3.     <meta charset="UTF-8">
  4.     <title>等体系推动静</title>
  5.     <script src="https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js"></script>
  6.     <script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script>
  7.     <script src="https://code.jquery.com/jquery-3.2.0.min.js"
  8.             integrity="sha256-JAW99MJVpJBGcbzEuXk4Az05s/XyDdBomFqNlM3ic+I=" crossorigin="anonymous"></script>
  9.     <script type="text/javascript">
  10.         var stompClient = null;
  11.         function setConnected(connected) {
  12.             document.getElementById("connect").disabled = connected;
  13.             document.getElementById("disconnect").disabled = !connected;
  14.             $("#response").html();
  15.         }
  16.         function connect() {
  17.              var socket = new SockJS("http://localhost:9908/publicServer");
  18.             stompClient = Stomp.over(socket);
  19.             stompClient.connect({}, function (frame) {
  20.                 setConnected(true);
  21.                 console.log(&#39;Connected: &#39; + frame);
  22.                 stompClient.subscribe(&#39;/topic/all&#39;, function (response) {
  23.                     var responseData = document.getElementById(&#39;responseData&#39;);
  24.                     var p = document.createElement(&#39;p&#39;);
  25.                     p.style.wordWrap = &#39;break-word&#39;;
  26.                     p.appendChild(document.createTextNode(response.body));
  27.                     responseData.appendChild(p);
  28.                 });
  29.             },{});
  30.         }
  31.         function disconnect() {
  32.             if (stompClient != null) {
  33.                 stompClient.disconnect();
  34.             }
  35.             setConnected(false);
  36.             console.log("Disconnected");
  37.         }
  38.         function sendMsg() {
  39.             var content = document.getElementById(&#39;content&#39;).value;
  40.             stompClient.send("/all",JSON.stringify({&#39;content&#39;: content}));
  41.         }
  42.     </script>
  43. </head>
  44. <body onload="disconnect()">
  45. <noscript><h2 style="color: #ff0000">Seems your browser doesn&#39;t support Javascript! Websocket relies on Javascript being
  46.     enabled. Please enable
  47.     Javascript and reload this page!</h2></noscript>
  48. <div>
  49.     <div>
  50.         <labal>毗连播送频讲</labal>
  51.         <button id="connect" onclick="connect();">Connect</button>
  52.         <labal>打消毗连</labal>
  53.         <button id="disconnect" disabled="disabled" onclick="disconnect();">Disconnect</button>
  54.     </div>
  55.     <div id="conversationDiv">
  56.         <labal>播送动静</labal>
  57.         <input type="text" id="content"/>
  58.         <button id="sendMsg" onclick="sendMsg();">Send</button>
  59.     </div>
  60.     <div>
  61.         <labal>领受到的动静:</labal>
  62.         <p id="responseData"></p>
  63.     </div>
  64. </div>
  65. </body>
  66. </html>
复造代码
简析: 
150024ks11g6n2zss9zns3.jpg

连成一气,我们模仿体系后端给前端推收播送动静,经由过程接心模仿:
 
TestController.java
  1. /**
  2. * @Author JCccc
  3. * @Description
  4. * @Date 2021/8/20 8:53
  5. */
  6. @Controller
  7. public class TestController {
  8.     @Autowired
  9.     public SimpMessagingTemplate template;
  10.     /**
  11.      * 播送
  12.      *
  13.      * @param msg
  14.      */
  15.     @ResponseBody
  16.     @RequestMapping("/pushToAll")
  17.     public void subscribe( @RequestBody Message msg) {
  18.         template.convertAndSend("/topic/all", msg.getContent());
  19.     }
  20. }
复造代码
简析:

我们推收动静,间接用 SimpMessagingTemplate ,
用的是convertAndSend 播送方法推收到关于的主标题问题的天 destination 。
(能够看到实在另有convertAndSendToUser ,没有焦急,前面会道,那是收收给某个毗邻用户的)
150024nt0fappe0irhprr9.jpg


 间接把项目跑起去,翻开页里开端测试:
150024pmyyxeox88wbery5.jpg

 我们先面击connect ,毗邻胜利:
150025fj8netnhgzbgzrnn.jpg

能够看到实践上stomp.min.js 终极也是转化成为 ws/wss这类方法胜利毗邻:
150025r1yqub311rydhikb.jpg


挪用测试接心,推收播送动静:
150026tb9nhc98oopb40n9.jpg

 
150026p0qhrs1p7ep0e3e1.jpg

 正在console实在也能看到:
150026xh9jcjjpl9thcjjb.jpg


 播送功用便到那,接下去是 面对面。

前端页里:

privateExample.html
  1. <html>
  2. <head>
  3.     <meta charset="UTF-8">
  4.     <title>聊起去</title>
  5.     <script src="https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js"></script>
  6.     <script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script>
  7.     <script src="https://code.jquery.com/jquery-3.2.0.min.js"
  8.             integrity="sha256-JAW99MJVpJBGcbzEuXk4Az05s/XyDdBomFqNlM3ic+I=" crossorigin="anonymous"></script>
  9.     <script type="text/javascript">
  10.         var stompClient = null;
  11.         function setConnected(connected) {
  12.             document.getElementById("connect").disabled = connected;
  13.             document.getElementById("disconnect").disabled = !connected;
  14.             $("#response").html();
  15.         }
  16.         function connect() {
  17.             var socket = new SockJS("http://localhost:9908/privateServer");
  18.             stompClient = Stomp.over(socket);
  19.             stompClient.heartbeat.outgoing = 20000;
  20.             // client will send heartbeats every 20000ms
  21.             stompClient.heartbeat.incoming = 0;
  22.             stompClient.connect({}, function (frame) {
  23.                 setConnected(true);
  24.                 console.log(&#39;Connected: &#39; + frame);
  25.                 stompClient.subscribe(&#39;/user/&#39; + document.getElementById(&#39;user&#39;).value + &#39;/message&#39;, function (response) {
  26.                     var responseData = document.getElementById(&#39;responseData&#39;);
  27.                     var p = document.createElement(&#39;p&#39;);
  28.                     p.style.wordWrap = &#39;break-word&#39;;
  29.                     p.appendChild(document.createTextNode(response.body));
  30.                     responseData.appendChild(p);
  31.                 });
  32.             });
  33.         }
  34.         function disconnect() {
  35.             if (stompClient != null) {
  36.                 stompClient.disconnect();
  37.             }
  38.             setConnected(false);
  39.             console.log("Disconnected");
  40.         }
  41.         function sendMsg() {
  42.             var headers = {
  43.                 login: &#39;mylogin&#39;,
  44.                 passcode: &#39;mypasscode&#39;,
  45. // additional header
  46.                 &#39;accessToken&#39;: &#39;HWPO325J9814GBHJF933&#39;
  47.             };
  48.             var content = document.getElementById(&#39;content&#39;).value;
  49.             var to = document.getElementById(&#39;to&#39;).value;
  50.             stompClient.send("/alone", {&#39;accessToken&#39;: &#39;HWPO325J9814GBHJF933&#39;}, JSON.stringify({
  51.                 &#39;content&#39;: content,
  52.                 &#39;to&#39;: to
  53.             }));
  54.         }
  55.     </script>
  56. </head>
  57. <body onload="disconnect()">
  58. <noscript><h2 style="color: #ff0000">Seems your browser doesn&#39;t support Javascript! Websocket relies on Javascript being
  59.     enabled. Please enable
  60.     Javascript and reload this page!</h2></noscript>
  61. <div>
  62.     <div>
  63.         <labal>毗连用户</labal>
  64.         <input type="text" id="user"/>
  65.         <button id="connect" onclick="connect();">Connect</button>
  66.     </div>
  67.     <div>
  68.         <labal>打消毗连</labal>
  69.         <button id="disconnect" disabled="disabled" onclick="disconnect();">Disconnect</button>
  70.     </div>
  71.     <div id="conversationDiv">
  72.         <labal>收收动静</labal>
  73.         <div>
  74.             <labal>内乱容</labal>
  75.             <input type="text" id="content"/>
  76.         </div>
  77.         <div>
  78.             <labal>收给谁</labal>
  79.             <input type="text" id="to"/>
  80.         </div>
  81.         <button id="sendMsg" onclick="sendMsg();">Send</button>
  82.     </div>
  83.     <div>
  84.         <labal>领受到的动静:</labal>
  85.         <p id="responseData"></p>
  86.     </div>
  87. </div>
  88. </body>
  89. </html>
复造代码
简析:

150027gpyc7pdpdviobpf3.jpg


连成一气,我们模仿体系后端给前端推收面对面动静(指定某个用户),经由过程接心模仿:
  1.     /**
  2.      * 面对面
  3.      */
  4.     @ResponseBody
  5.     @RequestMapping("/pushToOne")
  6.     public void queue(@RequestBody Message msg) {
  7.         System.out.println("进进办法");
  8.         /*利用convertAndSendToUser办法,第一个参数为用户id,此时js中的定阅地点为
  9.         "/user/" + 用户Id + "/message",此中"/user"是牢固的*/
  10.         template.convertAndSendToUser(msg.getTo(), "/message", msg.getContent());
  11.     }
复造代码
用的是convertAndSendToUser 推收到指定的用户 ,关于的主标题问题的天 destination(/message) 

或许看到那里,您会觉得很奇异,为何我们推的主题是 /message,可是前端定阅的倒是
 
  "/user/" + 用户Id + "/message"

我们间接看源码:
150027yzi82wdwl9928z9w.jpg

 
150028d9ooobzsgoakvvra.jpg

 ok,该当不消多道,代码帮我们本人拼接起去了,跟前端定阅划定规矩连结分歧。

间接跑项目,测试一下:

模仿我们毗邻的用户标识 19901 ,毗邻胜利
150028orltraap255zv4ta.jpg


操纵postman挪用我们的测试接心,模仿体系指定推收动静到 19901 那小我私家 :
150029scmrlrar4epiepvc.jpg


然后也给20011收收一下动静:
150029qik7dridrikrkn3q.jpg

 然后看到对应的用户也能支到对应的动静:
150030c5tosbe11esudmkm.jpg

对面推收,播送推收,也曾经终了了 。

这类状况便是相称于操纵http接心方法,来撮合后端效劳做 动静推收。

实在spring借供给了一些好玩的注解,

@MessageMapping  那个注解是对称于  @EnableWebSocketMessageBroker
150030rpblt2ctblmbc6pk.jpg


也便是道,假如我们操纵@EnableWebSocketMessageBroker ,那末我们正在接心上里实在就可以间接操纵  @MessageMapping。

怎样用?
150031rah0j7ltta9afybo.jpg

然后前端代码内里 的操纵:
150031ae5lvp8nzzbenpv5.jpg

 如许我们就能够经由过程前端间接挪用相关接心了:
150032izjsfl0hgsllghjf.jpg

小我私家觉得实在出有须要操纵那个注解,间接经由过程前端挪用后端效劳代码,我们效劳端去按照Message内里 的 收收圆、吸取圆、动静规范(面对面、播送)就能够间接完成相关也营业场景了。


ok,该篇便到此。

下一篇,给各人带去怎样打点websocket背载成绩 。













免责声明:假如进犯了您的权益,请联络站少,我们会实时删除侵权内乱容,感谢协作!
1、本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,按照目前互联网开放的原则,我们将在不通知作者的情况下,转载文章;如果原文明确注明“禁止转载”,我们一定不会转载。如果我们转载的文章不符合作者的版权声明或者作者不想让我们转载您的文章的话,请发帖留言提供原创证明,我们将积极配合您!
2、本网站转载文章仅为传播更多信息之目的,凡在本网站出现的信息,均仅供参考。本网站将尽力确保所提供信息的准确性及可靠性,但不保证信息的正确性和完整性,且不对因信息的不正确或遗漏导致的任何损失或损害承担责任。
3、任何透过本网站网页而链接及得到的资讯、产品及服务,本网站概不负责,亦不负任何法律责任。
4、本网站所刊发、转载的文章,其版权均归原作者所有,如其他媒体、网站或个人从本网下载使用,请在转载有关文章时务必尊重该文章的著作权,保留本网注明的“稿件来源”,并自负版权等法律责任。
回复

使用道具 举报

 
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则