当前位置:   article > 正文

微服务使用SockJs+Stomp实现Websocket 前后端实例 | Vuex形式断开重连、跨域等等问题踩坑(二)_sockjs 断开重连

sockjs 断开重连

大家好,我是程序员大猩猩。

上次我们实践了,Java后端如何完成SockJS+Stomp的配置实现。

那么今天我们做一下web vue端的是如何来实现的。

这里我罗列一下,我实现所使用的vue版本。

  1. "sockjs-client": "^1.5.0",
  2. "stompjs": "^2.3.3",
  3. "vue": "^3.0.0",
  4. "vuex": "^4.1.0"
  5. // 本地Node版本号
  6. node v14.21.3

这里,我从创建好工程后,导入工程开始说起,说说我碰到的问题及我的解决方法,一遍大家更好的理解。

首先,我是采用vue create *** 来创建一个项目,中间选择使用vuex组件。待项目创建后,我这里使用WebStorm开发工具,将项目导入后,工具会自动让我们npm install。

在项目的根目录

  1. npm install sockjs-client
  2. npm install stompjs

或者

package.json->dependencies->下添加

  1. "sockjs-client": "^1.5.0",
  2. "stompjs""^2.3.3",

因为我们是需要在vuex中实现SockJs的,所以在src内创建store目录,并且完成一下代码store/index.js

  1. import modules from './modules'
  2. import { createStore } from 'vuex'
  3. export default new createStore({
  4. modules,
  5. strict: false
  6. })

在store目录下创建modules文件目录,目录内新增index.js和websocket.js

  1. // index.js
  2. const files = require.context('.', false, /\.js$/)
  3. const modules = {}
  4. files.keys().forEach(key => {
  5. if (key === './index.js') return
  6. modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default
  7. })
  8. export default modules
  9. // websocket.js
  10. import {createStore} from 'vuex'
  11. import SockJS from 'sockjs-client'
  12. import Stomp from 'stompjs'
  13. import config from '../../config/index'
  14. // 后端ws连接 http开头形式
  15. const url = config.scokJsUrl

​​​​​​​接下来我们分析一下,websocket在前端需要什么操作呢?

1. 初始化

  1. WEBSOCKET_INIT({
  2. commit,
  3. state
  4. }, header) {
  5. commit('WEBSOCKET_INIT', header)
  6. },

​​​​​​​

2. 发送消息

  1. WEBSOCKET_SEND({
  2. commit,
  3. state
  4. }, p) {
  5. commit('WEBSOCKET_SEND', p)
  6. },

​​​​​​​

3. 订阅

  1. WEBSOCKET_UNSUBSRCIBE({
  2. commit,
  3. state
  4. }, p) {
  5. commit('WEBSOCKET_UNSUBSRCIBE', p)
  6. },

4. 断开

  1. WEBSOCKET_DISCONNECT({
  2. commit,
  3. state
  4. }) {
  5. commit('WEBSOCKET_DISCONNECT')
  6. }

​​​​​​​我们在store注册actions,actions注册以上方法。然后在mutations内实现以上方法。

  1.  mutations: {
  2. WEBSOCKET_INIT(state, header) {
  3. if (state.stompClient == null || !state.stompClient.connected) {
  4. state.url = url
  5. if (state.stompClient != null && state.websocket.readyState === SockJS.OPEN) {
  6. state.stompClient.disconnect(() => {
  7. this.commit('WEBSOCKET_CONNECT', header)
  8. })
  9. } else if (state.stompClient != null && state.websocket.readyState === SockJS.CONNECTING) {
  10. console.log('连接正在建立')
  11. return
  12. } else {
  13. this.commit('WEBSOCKET_CONNECT', header)
  14. }
  15.             // 断线重连实现块
  16.            // 断线重连实现块
  17.            // 断线重连实现块
  18.            // 断线重连实现块
  19. } else {
  20. console.log('连接已建立成功,不再执行')
  21. }
  22. },
  23. WEBSOCKET_CONNECT(state, header) {
  24. const _this = this
  25. console.log('URL链接 ' + state.url)
  26. const websock = new SockJS(state.url)
  27. console.log('URL链接 ' + websock)
  28. state.websocket = websock
  29. // 获取STOMP子协议的客户端对象
  30. const stompClient = Stomp.over(websock)
  31. stompClient.connect(header,
  32. () => {
  33. console.log('链接成功!')
  34. state.listenerList.forEach(item => {
  35. state.stompClient.subscribe(item.topic, item.callback, header)
  36. })
  37. },
  38. (err) => {
  39. console.log('链接失败!', err)
  40. // 第一次连接失败和连接后断开连接都会调用这个函数 此处调用重连
  41. setTimeout(() => {
  42. _this.commit('WEBSOCKET_INIT', header)
  43. }, 1000)
  44. }
  45. )
  46. state.stompClient = stompClient
  47. },
  48. WEBSOCKET_SEND(state, p) {
  49. state.stompClient.send(p.topic, {userId: p.userId}, p.data)
  50. },
  51. WEBSOCKET_UNSUBSRCIBE(state, p) {
  52. state.stompClient.unsubscribe(p)
  53. for (let i = 0; i < state.listenerList.length; i++) {
  54. if (state.listenerList[i].topic === p) {
  55. state.listenerList.splice(i, 1)
  56. console.log('解除订阅:' + p + ' size:' + state.listenerList.length)
  57. break
  58. }
  59. }
  60. },
  61. WEBSOCKET_DISCONNECT(state) {
  62. if (state.stompClient != null) {
  63. console.log('关闭连接')
  64. state.stompClient.disconnect()
  65. }
  66. }
  67. },

​​​​​​​sockJs主要连接代码为WEBSOCKET_CONNECT内:

  1. const websock = new SockJS(state.url)
  2. console.log('URL链接 ' + websock)
  3. state.websocket = websock
  4. // 获取STOMP子协议的客户端对象
  5. const stompClient = Stomp.over(websock)

    当websocket.js实现完成后,我们也基本完成的vue端的实现,接下来在现实端页面,调用vuex即可。参考我的methods

  1. methods: {
  2. disconnect() {
  3. clearInterval(this.connectionTimer);
  4. clearInterval(this.timer);
  5. this.$websocket.dispatch("WEBSOCKET_DISCONNECT");
  6. },
  7. stompConnection() {
  8.     const loginUserId = "my you Dad";
  9. const headers = {
  10. token: "SSSRIRTOKEN326458",
  11. userId: loginUserId
  12. };
  13. this.$websocket.dispatch("WEBSOCKET_INIT", headers);
  14. const _this = this;
  15. const stompClient = this.$websocket.getters.stompClient();
  16. this.connectionTimer = setInterval(() => {
  17. if (stompClient != null && stompClient.connected) {
  18. clearInterval(this.connectionTimer);
  19. _this.subscriptions = [];
  20. _this.subscriptions.push(stompClient.subscribe("/user/" + loginUserId + "/queue/ping", msg => {
  21. console.log("我要的ping信息" + msg.body);
  22. }));
  23. // 定时推送订阅信息
  24. this.timer = setInterval(function () {
  25. const header = {
  26. userId: loginUserId
  27. };
  28. stompClient.send("/ping", header, "ping");
  29. }, 10000);
  30. } else {
  31. console.log("等待连接成功");
  32. }
  33. }, 500);
  34. }
  35. }

​​​​​​​前后端一起启动项目,查看结果。

图片

StompJS的一些设置:

  1. // 关闭控制台打印
  2. // stompClient.debug = null
  3. // stompClient.heartbeat.outgoing = 20000
  4. // // 客户端不从服务端接收心跳包
  5. // stompClient.heartbeat.incoming = 0

​​​​​​​

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

闽ICP备14008679号