当前位置:   article > 正文

基于SockJS+Stomp的WebSocket实现_sockjs websocket

sockjs websocket

前言

    之前做个一个功能,通过websocket长链接接收后台推送的数据,然后在前端动态渲染。一直没来的及输出个文档,现在输出一下。

WebSocket介绍

    WebSocket 是一种在 Web 应用中实现实时通信的方法,它可以在客户端和服务器端之间建立长连接,实现实时消息传递。

    传统的WenSocket在使用过程中可能会有各种问题,什么性能方面啊、浏览器兼容方面啊,各种问题。之前做个一版用传统的WebSocket实现车辆实时位置推送功能,因为后台是广播模式进行的消息推送,一辆车一个通道,当车的数量多起来后,浏览器或WebSocket就直接罢工了,我实测了一下,这个边界值大概在253 - 256。所以,急需更换方案。

SockJS 和 Stomp 库介绍

    SockJS 和 Stomp 是两个常用的 WebSocket 库,它们可以帮助我们更方便地实现 WebSocket 功能。相较于传统的WebSocket,它的优点有很多:

  1. 兼容性更好:能够在浏览器和服务器之间创建低延迟、双向通信通道,能够兼容大多数浏览器和服务器,包括一些老旧的浏览器和服务器。

  2. 自适应性更强:能够根据环境和浏览器自动选择最佳的通信方式,包括WebSocket、XHR流或JSONP轮询等。这样能够更好的保证通信的质量和稳定性。

  3. 底层通信更加可靠:使用了一些底层通信协议,例如XHR流或JSONP轮询,它们能够更好的处理网络故障、代理服务器等问题,从而提高通信的可靠性。

  4. 开发效率更高:提供了一些高级的功能,例如订阅和发布模式、心跳检测等,能够更快速地开发实时Web应用程序。

  5. 跨语言和平台更容易:STOMP协议是一种基于文本的协议,因此它能够更容易地跨语言和平台通信。这意味着您可以使用不同的编程语言和框架来构建您的Web应用程序,并且能够无缝地集成在一起。

总之,使用SockJS + STOMPJS相较于传统模式的Websocket能够更好的保证通信的质量和稳定性,同时能够提高开发效率,从而更好地满足实时Web应用程序的需求。

SockJS

    SockJS 是一个 JavaScript 库,用于在浏览器和 Web 服务器之间建立实时通信连接。它提供了一个 WebSocket 的备选方案,并兼容多种浏览器和 Web 服务器。SockJS 会自动检测浏览器是否支持 WebSocket,如果不支持,则会自动降级为其他协议(如 long polling、iframe、JSONP 等)。

Stomp

    Stomp 是一种简单的消息传递协议,它允许客户端和服务器之间进行异步消息传递。Stomp 协议定义了一个消息格式,允许客户端和服务器进行消息的订阅和发布。Stomp 可以在 Web 应用中使用,也可以在其他应用中使用(如 Android、iOS 等)。

WebSocket 功能类实现

 - 上代码 - 

1. 引入 SockJS 和 Stomp 库

  1. npm install sockjs-client --save
  2. npm install stompjs --save
  1. import SockJS from "sockjs-client";
  2. import Stomp from "stompjs";

2、类实现

  1. class webSocket {
  2. //构造函数
  3. constructor() {
  4. this.tryTimes = 1; // 重连次数
  5. this.callback = null; // 回调函数
  6. this.stompClient = null; // stomp对象
  7. this.reconTimeout = null; //重连延时器
  8. this.sendTimeout = null; // 重发心跳延时器 - 10s发一次
  9. this.vm = null;
  10. }
  11. /** socket连接 */
  12. connectionSocket() {
  13. //连接SockJS
  14. let socket = new SockJS(`${this.getSocketUrl()}`);
  15. // 获取STOMP子协议的客户端对象
  16. this.stompClient = Stomp.over(socket);
  17. //日志不打印
  18. this.stompClient.debug = () => {};
  19. // 向服务器发起websocket连接
  20. this.stompClient.connect({ userId: '自己订阅送的id' }, () => {
  21. //tryTimes定义重置
  22. this.tryTimes = 1;
  23. //订阅消息
  24. this.subscribeToServer();
  25. //心跳单独通道
  26. this.stompClient.subscribe(`/server/net/${'自己订阅送的id'}`, (response) => {
  27. if (response && response.body && JSON.parse(response.body).code == '0') {
  28. //再次进行心跳发送
  29. this.heartCheck();
  30. }
  31. });
  32. }, (err) => {
  33. // 连接发生错误时的处理函数
  34. console.log('失败');
  35. if(this.vm.$message) this.vm.$message({ message: '连接发生错误,请刷新网页再次连接!', type: 'warning' });
  36. });
  37. }
  38. /** 订阅服务端 */
  39. subscribeToServer() {
  40. // 订阅服务端提供的某个topic
  41. this.stompClient.subscribe(`/server/${topic的id}`, (response) => {
  42. if (response) {
  43. if(this.callback) this.callback(response);
  44. }
  45. });
  46. }
  47. /** 赋值、初始化socket */
  48. initWebSocket(back, me) {
  49. this.vm = me;
  50. //列表赋值
  51. this.callback = back;
  52. //初始化连接
  53. this.connectionSocket();
  54. //加载心跳
  55. this.heartCheck();
  56. }
  57. /** 重连 */
  58. reconnect() {
  59. this.destroy();
  60. if(this.tryTimes > 10) {
  61. if(this.vm.$message) this.vm.$message({ message: '重连次数已达上限,连接失败。请刷新网页再次连接!', type: 'warning' });
  62. return;
  63. }
  64. this.tryTimes++;
  65. //再次连接
  66. this.connectionSocket();
  67. this.heartCheck();
  68. }
  69. /** 心跳检测机制 */
  70. heartCheck() {
  71. //先清除重连机制
  72. if(this.reconTimeout) clearTimeout(this.reconTimeout);
  73. let me = this;
  74. me.sendTimeout = setTimeout(() => {
  75. me.sendSocket({ to: `/server/net/${'自己订阅送的id'}` });
  76. //重连机制,十秒不被清除代表已经断开,进行重连
  77. me.reconTimeout = setTimeout(() => {
  78. me.reconnect();
  79. }, 10000);
  80. }, 10000);
  81. }
  82. /** 发送消息 */
  83. sendSocket(params) {
  84. try {
  85. this.stompClient.send("/client/path/points", {}, JSON.stringify(params));
  86. } catch (error) {
  87. console.log("发生异常了-------", error);
  88. }
  89. }
  90. /** 销毁 */
  91. destroy() {
  92. // 断开连接,清除定时器
  93. if (this.stompClient) this.stompClient.disconnect();
  94. if (this.reconTimeout) clearTimeout(this.reconTimeout);
  95. if (this.sendTimeout) clearTimeout(this.sendTimeout);
  96. }
  97. /** 获取动态socket地址,http环境下使用http,https环境下使用https访问websocket */
  98. getSocketUrl() {
  99. return window.location.protocol + '//' + process.env.VUE_APP_WS_API + process.env.VUE_APP_WS_CTX;
  100. }
  101. }
  102. const WebSocket = new webSocket();
  103. export default WebSocket;

3、使用

  1. //webSockets类
  2. webSockets.initWebSocket((res) => {
  3. console.log("推送的消息------", res);
  4. }, this)

4、记得在不用的时候干掉订阅

  1. destroyed() {
  2. //离开页面,干掉websocket
  3. webSockets.destroy();
  4. },

总结

    代码中去除了部分的业务逻辑代码,按照需求添加即可。如果是想要一通道多订阅的话,可让后台搞一个动态的topic,给方法内扔一个数组进去,遍历数组,生成多个订阅。

ok,结束,我的愿望是世界和平!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/178656
推荐阅读
相关标签
  

闽ICP备14008679号