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

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

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

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

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

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

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

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

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

在项目的根目录

npm install sockjs-client
npm install stompjs

或者

package.json->dependencies->下添加

"sockjs-client": "^1.5.0",
"stompjs": "^2.3.3",

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

import modules from './modules'

import { createStore } from 'vuex'
export default new createStore({
  modules,
  strict: false
})

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

// index.js

const files = require.context('.', false, /\.js$/)
const modules = {}

files.keys().forEach(key => {
    if (key === './index.js') return
    modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default
})

export default modules

// websocket.js

import {createStore} from 'vuex'
import SockJS from 'sockjs-client'
import Stomp from 'stompjs'
import config from '../../config/index'
// 后端ws连接 http开头形式
const url = config.scokJsUrl

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

1. 初始化

WEBSOCKET_INIT({
                   commit,
                   state
               }, header) {
    commit('WEBSOCKET_INIT', header)
},

​​​​​​​

2. 发送消息

WEBSOCKET_SEND({
                   commit,
                   state
               }, p) {
    commit('WEBSOCKET_SEND', p)
},

​​​​​​​

3. 订阅

WEBSOCKET_UNSUBSRCIBE({
                          commit,
                          state
                      }, p) {
    commit('WEBSOCKET_UNSUBSRCIBE', p)
},

4. 断开

WEBSOCKET_DISCONNECT({
                         commit,
                         state
                     }) {
    commit('WEBSOCKET_DISCONNECT')
}

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

 mutations: {
    WEBSOCKET_INIT(state, header) {
        if (state.stompClient == null || !state.stompClient.connected) {
            state.url = url
            if (state.stompClient != null && state.websocket.readyState === SockJS.OPEN) {
                state.stompClient.disconnect(() => {
                    this.commit('WEBSOCKET_CONNECT', header)
                })
            } else if (state.stompClient != null && state.websocket.readyState === SockJS.CONNECTING) {
                console.log('连接正在建立')
                return
            } else {
                this.commit('WEBSOCKET_CONNECT', header)
            }
            // 断线重连实现块
            // 断线重连实现块
            // 断线重连实现块
            // 断线重连实现块
        } else {
            console.log('连接已建立成功,不再执行')
        }
    },
    WEBSOCKET_CONNECT(state, header) {
        const _this = this
        console.log('URL链接 ' + state.url)
        const websock = new SockJS(state.url)
        console.log('URL链接 ' + websock)
        state.websocket = websock
        // 获取STOMP子协议的客户端对象
        const stompClient = Stomp.over(websock)
        stompClient.connect(header,
            () => {
                console.log('链接成功!')
                state.listenerList.forEach(item => {
                    state.stompClient.subscribe(item.topic, item.callback, header)
                })
            },
            (err) => {
                console.log('链接失败!', err)
                // 第一次连接失败和连接后断开连接都会调用这个函数 此处调用重连
                setTimeout(() => {
                    _this.commit('WEBSOCKET_INIT', header)
                }, 1000)
            }
        )
        state.stompClient = stompClient
    },
    WEBSOCKET_SEND(state, p) {
        state.stompClient.send(p.topic, {userId: p.userId}, p.data)
    },
    WEBSOCKET_UNSUBSRCIBE(state, p) {
        state.stompClient.unsubscribe(p)
        for (let i = 0; i < state.listenerList.length; i++) {
            if (state.listenerList[i].topic === p) {
                state.listenerList.splice(i, 1)
                console.log('解除订阅:' + p + ' size:' + state.listenerList.length)
                break
            }
        }
    },
    WEBSOCKET_DISCONNECT(state) {
        if (state.stompClient != null) {
            console.log('关闭连接')
            state.stompClient.disconnect()
        }
    }
},

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

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

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

methods: {
  disconnect() {
    clearInterval(this.connectionTimer);
    clearInterval(this.timer);
    this.$websocket.dispatch("WEBSOCKET_DISCONNECT");
  },
  stompConnection() {
    const loginUserId = "my you Dad";
    const headers = {
      token: "SSSRIRTOKEN326458",
      userId: loginUserId
    };
    this.$websocket.dispatch("WEBSOCKET_INIT", headers);

    const _this = this;
    const stompClient = this.$websocket.getters.stompClient();
    this.connectionTimer = setInterval(() => {
      if (stompClient != null && stompClient.connected) {
        clearInterval(this.connectionTimer);
        _this.subscriptions = [];
        _this.subscriptions.push(stompClient.subscribe("/user/" + loginUserId + "/queue/ping", msg => {
          console.log("我要的ping信息" + msg.body);
        }));
        // 定时推送订阅信息
        this.timer = setInterval(function () {
          const header = {
            userId: loginUserId
          };
          stompClient.send("/ping", header, "ping");
        }, 10000);
      } else {
        console.log("等待连接成功");
      }
    }, 500);
  }
}

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

图片

StompJS的一些设置:

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

​​​​​​​

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/583391.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

android studio拍照功能问题解决

1.点击拍照功能直接闪退 2.拍照后不能选择确认键&#xff0c;无法保存 上述是在android studio做项目中经常会使用到模拟器或真机的拍照功能时主要遇到的两个问题。 解决方法&#xff1a; 1.直接闪退问题&#xff1a; if(Build.VERSION.SDK_INT>Build.VERSION_CODES.N)…

谈谈进些年的BLE开发项目

加zkhengyang可申请加入蓝牙音频研究开发交流答疑群(课题组) 最早接触BLE项目是在做一款女性按摩器产品上&#xff0c;所谓的生活用品&#xff0c;用的是TI CC2640&#xff0c;资料齐全&#xff0c;上手快&#xff0c;配合手机app通讯开发&#xff0c;当然这个是单模的蓝牙芯…

学习C语言的指针

有一阵没更新了&#xff0c;因为最近比较繁忙&#xff0c;所以更新比较慢&#xff0c;还在慢慢学习 话不多说&#xff0c;开始今天的内容&#xff0c;聊一聊C语言指针。 很多小伙伴可能会被指针这个名字吓到&#xff0c;觉得很难&#xff0c;实际上确实有点难&#xff0c;但是…

cesium教程

环境搭建 vscode安装Visual Studio Code - Code Editing. Redefined nodejs安装Node.js — Run JavaScript Everywhere cesium源码下载编译 cesium官网下载源码https://cesium.com/downloads/ 解压下载的源码 VsCode打开远吗&#xff0c;找到index.html,右键打开 Open wit…

职场人是如何被拉开差距的?

事实上&#xff0c;职场人的差距从第一天就拉开了。 心理学里有一个词&#xff0c;叫做“首因效应&#xff0c;说的是人们在第一次接触时形成的印象&#xff0c;将会决定后续认知的基调。 入职第一天&#xff0c;从自我介绍开始&#xff0c;展示自己的特长&#xff0c;给大家…

unity项目《样板间展示》开发:菜单界面

unity项目《样板间展示》开发&#xff1a;菜单界面 前言UI菜单创建逻辑实现结语 前言 这是这个项目demo教程的最后一节&#xff0c;这节是菜单界面部分的创建 UI菜单创建 创建一个新的场景&#xff0c;在Scene文件中右键选择Create->Scene&#xff0c;创建新的场景 在场景…

【服务器部署篇】Linux下快速安装Jenkins

作者介绍&#xff1a;本人笔名姑苏老陈&#xff0c;从事JAVA开发工作十多年了&#xff0c;带过刚毕业的实习生&#xff0c;也带过技术团队。最近有个朋友的表弟&#xff0c;马上要大学毕业了&#xff0c;想从事JAVA开发工作&#xff0c;但不知道从何处入手。于是&#xff0c;产…

Elasticsearch实现hotel索引库自动补全、拼音搜索功能

Elasticsearch实现hotel索引库自动补全、拼音搜索功能 在这里边我们有两个字段需要用拼音分词器&#xff0c;一个name字段&#xff0c;一个all字段。 然后我们还需要去实现自动补全&#xff0c;而自动补全对应的字段必须使用completion类型。目前我们酒店里面所有的字段都采用的…

暴雨信息| AI“速”不可挡,倒逼算力巨变!

「 “当某一天人工智能的智慧超越人类&#xff0c;你会发现人工智能将会以迅雷不及掩耳之势改变世界&#xff0c;那个改变是不可逆的&#xff0c;极其迅速。” 」 暴雨信息副董事长孙辉在“IPF2024”上的这个观点&#xff0c;正是当今世界在AI影响下急速前行的真实写照。 记得…

高压、单通道、轨对轨输入输出功率运算放大器RS8471

RS8471是一款高压、单通道、轨对轨输入输出的功率运算放大器&#xff0c;它的工作电压范围在4.5V到24V&#xff0c;最大峰值输出电流2.5A&#xff0c;失调电压为3mV&#xff0c;增益带宽积为25MHz&#xff0c;并提供65V/us的高压摆率&#xff0c;确保输出信号快速建立”,这些特…

[Java EE] 多线程(五):单例模式与阻塞队列

1. 单例模式 单例模式是校招中最长考的设计模式之一,首先我们来谈一谈什么是设计模式: 设计模式就好像象棋中的棋谱一样,如果红方走了什么样的局势,黑方就有一定地固定地套路,来应对这样的局势,按照固定地套路来,可以保证在该局势下不会吃亏. 软件开发也是同样的道理,有很多…

(十二)Servlet教程——HttpServletResponse接口

HttpServletResponse接口继承自ServletResponse接口&#xff0c;HttpServletResponse用来封装HTTP响应消息&#xff0c;简称response对象。 每次请求一个Servlet&#xff0c;Servlet容器就会针对每次请求创建一个response对象&#xff0c;并把它作为参数传递给Servlet的service…

Linux网络-文件传输协议之FTP服务(附带命令及截图)

目录 一.FTP简介 二.FTP的数据模式 1.主动模式 2.被动模式 3.两种模式比较 三.安装配置vsftpd 1.安装vsftpd 1.1.安装前关闭防火墙 1.2.安装vsftpd 1.3.查看 1.4.备份 2.配置 3.重启后生效 四.相关实验 1.以win为例 1.1.设置并测试测试连通性 1.2.在终端里创建…

js逆向进阶篇-某团酒店

提示!本文章仅供学习交流,严禁用于任何商业和非法用途,未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,如有侵权,可联系本文作者删除! 案例分析: 先来看看请求中有哪些参数是需要我们逆向,如下: mtgsig、fp、roh…

Java包装类,128陷阱

包装类 基本数据类型都有自己对应的包装类&#xff0c;因为Java本质是面向对象编程的&#xff0c;一切的内容在Java看来都是对象 但是基本数据类型没有类&#xff0c;也没有对象&#xff0c;这样就有了矛盾 所以诞生了基本类型的包装类 基本数据类型&#xff1a; byte,short,…

知乎热议:未来几年,AI技术在科研领域将有哪些新的发展趋势或突破?

我是娜姐 迪娜学姐 &#xff0c;一个SCI医学期刊编辑&#xff0c;探索用AI工具提效论文写作和发表。 一年多以来&#xff0c;各种国内外的AI模型和应用应接不暇&#xff0c;从刚开始ChatGPT一家独大&#xff0c;到现在的百花齐放&#xff0c;各种AI模型各有千秋&#xff0c;一时…

星尘智能 AI 机器人 S1——国产机器人的巅峰之作

AI智能机器人真的太炸裂了 国产科技威武-CSDN直播AI智能机器人真的太炸裂了 国产科技威武https://live.csdn.net/v/382519 最近发现了一个国产的机器人&#xff0c;真的让人惊叹不已&#xff01;它就是星尘智能 AI 机器人 S1&#xff01; 这个机器人简直太牛逼了&#xff01;…

Stable Diffusion 参数介绍及用法

大模型 CheckPoint 介绍 作用&#xff1a;定调了作图风格&#xff0c;可以理解为指挥者 安装路径&#xff1a;models/Stable-diffusion 推荐&#xff1a; AnythingV5Ink_v32Ink.safetensors cuteyukimixAdorable_midchapter2.safetensors manmaruMix_v10.safetensors counterf…

2024年的Java版本选择?java 17 安装

文章目录 2024年的Java版本选择&#xff1f;java 1.8 和 java17 什么区别&#xff1f;java 17 安装windows 11安装java 17C:\Program Files\Common Files\Oracle\Java\javapath是什么 2024年的Java版本选择&#xff1f; 3年前&#xff0c;java 1.8是市场主流&#xff08;还有一…

STM32用HAL库函数实现硬件IIC

/*出处&#xff1a;【STM32入门教程-2024】第12集 IIC通信与温湿度传感器AHT20(DHT20)_哔哩哔哩_bilibili */ AHT20驱动 这篇笔记我主要介绍代码实现&#xff0c;想要了解原理的请自己看视频&#xff0c;我不过多赘述了。 AHT20通信数据帧格式&#xff1a; ①对照手册上的通…