当前位置: 首页 > news >正文

vue+websocket+Stomp组件实现前端长连接

1文件结构

image

2.重点文件夹中的文件代码以及作用

① 根目录中systemConfig文件夹中的main.js文件

/***作用:作为项目中的配置文件,放了websocket连接的url,用户名(admin),密码(123456)*项目中基础API等一些配置参数* ==================================*/
/* eslint-disable */
(function (global, factory) {"use strict";if (typeof module === "object" && typeof module.exports === "object") {module.exports = global.document ?factory(global) :function (w) {if (!w.document) {throw new Error('systemConfig must apply to a window with document');}return factory(w)}} else {factory(global)}})(typeof window !== 'undefined' ? window : this, function (window) {"use strict";const systemConfig = window.systemConfig = {/**** 该配置项中的路径配置会覆盖系统内部配置项,主要用于部署应用时,地址变动等情况。* =======================================================================* 请严格按照配置相修改,禁止添加任何其他内容至该文件中**/api: {// 开发地址配置mockBaseUrl: '',// 生成部署地址配置prodBaseUrl: '',},websocket: [{    // 下面的三个参数是需要和后端沟通的url: '',login: '',passcode: '',name: ''}],}return systemConfig
})

②根目录中的src下的config中的externalConfigDetect下的index.js文件

/**作用:对配置参数安全校验* ==============================================* Author: wang* Date: 2022.3.4**/
import systemConfig from 'systemConfig'class PlatformBaseConfig {constructor () {this.config = systemConfig}getConfig () {if (detectCurrectConfig(this.config)) {const { api, websocket } = this.configreturn {api,websocket,external: true}} else {console.error('外部配置文件引入失败,系统将采用内置原始配置。如需正常引用,请先检查外部配置项。')return {external: false}}}getApi () {return this.getConfig().api || {}}getWs () {return this.getConfig().websocket || []}
}// 对外部引入的对象做一些安全检查
function detectCurrectConfig (config) {if (typeof (config) !== 'object' || typeof (config) === 'undefined') return falseif (!config.api || !config.websocket) return falseconst apiKeys = Object.keys(config.api)if (apiKeys.indexOf('mockBaseUrl') === -1 || apiKeys.indexOf('prodBaseUrl') === -1) {return false}config.websocket.map((item) => {const wsKeys = Object.keys(item)if (wsKeys.indexOf('url') === -1 || wsKeys.indexOf('login') === -1 || wsKeys.indexOf('passcode') === -1) {return false}})return true
}export default new PlatformBaseConfig()

③根目录中的src下的config中的externalConfigDetect下的settings.js文件

/**作用:统一输出配置参数* Global Configurations* =========================* Author: wang* Date: 2022.3.4*/// 此文件只需要看Websocket 配置项即可
import platformBaseConfig from './externalConfigDetect'/*** API接口默认参数配置
*/
const baseConfig = {isMocked: process.env.NODE_ENV !== 'production',isDebug: process.env.NODE_ENV !== 'production',sep: '.'
}
export const API_DEFAULT_CONFIG = Object.assign(baseConfig, platformBaseConfig.getApi())/*** Websocket 配置项*/
const baseWsConfig = []
export const WS_CONFIG = Object.assign(baseWsConfig, platformBaseConfig.getWs())

④根目录中的src下的config中的plugins下的websocket.js文件

/*** ================================* Content: 使用class创建websocket* Author: wang* Date: 2022.3.4* Technology: Stomp组件 WebSocket* ================================*/// Stomp组件
import Stomp from 'stompjs'
import { WS_CONFIG } from '@/config/settings'
// import store from '@/plugins/store'
class DispatchWebsocket {// constructor 方法是类的构造函数,是一个默认方法,通过 new 命令创建对象实例时,自动调用该方法
  constructor ({ url, login, passcode }) {this.url = urlthis.ws = nullthis.client = nullthis.headers = {login: login,passcode: passcode}this.onConnect = {}this.onError = () => {}this.isConnect = falsethis.count = 0this.timer = null}createWSConnection (ws) {if (!ws && this.url) {return new Promise((resolve, reject) => {this.ws = new WebSocket(this.url)this.client = Stomp.over(this.ws)this.client.debug = falsethis.onConnect = () => {this.isConnect = trueresolve()}this.onError = () => {this.reconnectWSConnection()reject(new Error('创建websoket链接失败.'))}this.client.connect(this.headers, this.onConnect, this.onError)})} else {console.warn('已经创建了webscoket链接,不需要重复创建!')}}reconnectWSConnection () {this.isConnect = falseif (this.timer === null) {this.timer = setInterval(() => {if (this.count === 150) {console.log('ws重连5分钟未成功,请刷新页面')clearInterval(this.timer)return}this.ws = new WebSocket(this.url)this.client = Stomp.over(this.ws)this.client.debug = falsethis.handleSuccess = () => {console.log('重新连接成功!')this.count = 0this.isConnect = trueclearInterval(this.timer)this.timer = null}this.handleError = () => {console.error('重新连接失败!')const reconInv = setInterval(() => {clearInterval(reconInv)this.reconnectWSConnection()}, 10000)}this.client.connect(this.headers, this.handleSuccess, this.handleError)this.count++}, 2000)}}destroyWSConnection () {return new Promise((resolve) => {this.ws && this.client.disconnect(() => {this.isConnect = falseresolve()})})}
}export default {install (Vue) {WS_CONFIG.forEach((item) => {console.log('item', item)const ws = new DispatchWebsocket(item)ws.createWSConnection(Vue.prototype[`$ws${item.name}`])// 消息提示推送
      Object.defineProperty(Vue.prototype, `$ws${item.name}`, {value: ws})})// ws.createWSConnection()// Vue.prototype.$ws = websocket// 绑定websocket至原型对象
  }
}

⑤以上四步就是简单的创建websocket,这一步是如何将websocket挂载到vue项目中
在根目录的main.js文件中

import Vue from 'vue'
import App from '@/App.vue'
import router from '@/router'
import store from '@/store'
import ElementUI from 'element-ui'
import websocket from '@/plugins/websocket'import 'element-ui/lib/theme-chalk/index.css'Vue.use(ElementUI)
// 此处创建websocket在性能上还可以优化,项目中建议将websocket创建的时机放在用户登录成功之后
Vue.use(websocket)Vue.config.productionTip = falsenew Vue({router,store,render: h => h(App)
}).$mount('#app')

⑥使用

<template><div><el-button type="success" round @click="handleOpen">开启ws</el-button><el-button type="success" round @click="handleClose">关闭ws</el-button></div>
</template>
<script>
export default {data() {return {lineIdArray: ["6489", "63699"],lineSubscibes: [],};},mounted() {},methods: {handleOpen() {// JavaScript 类不是对象。它是 JavaScript 对象的模板。this.lineIdArray.forEach((lineId) => {this.subcribeLine(lineId);});},handleClose() {this.destroyWSConnection();},subcribeLine(lineId) {this.lineSubscibes[lineId] = this.$ws.client.subscribe(`/topic/pos.base.${lineId}.*`,(data) => {const busData = JSON.parse(data.body);console.log(busData, busData);});},destroyWSConnection() {console.log(this.lineSubscibes);if (this.lineIdArray.length > 0) {console.log("-------------------------------------------");for (let index = 0; index < this.lineIdArray.length; index++) {let unscr = this.lineSubscibes[this.lineIdArray[index]];console.log("unscr", unscr);if (unscr) {console.log(`执行了${unscr}`);unscr.unsubscribe();}}}},},
};
</script>

4.按照我提供的文件路劲和代码就能够创建出一个简单的websocket的demo,注意需要后端配合

http://www.zskr.cn/news/1466.html

相关文章:

  • 多字段排序工具类,支持树形
  • 同城黑卡小程序系统介绍
  • 365 快乐农场小程序介绍
  • 23Java基础之File
  • Linux GNU 工具集详解
  • 国产DevOps工具链崛起:Gitee如何重塑企业研发效能版图
  • docker部署ruoyi-cloud验证码问题记录
  • 【初赛】ip地址 - Slayer
  • 2025年物流行业CRM解决方案全解析:数字化时代的客户关系管理新范式 - SaaS软件
  • 记一次“若依微服务”启动系统模块时连不上nacos的问题
  • Qt/C++切换街道图/卫星图/混合图/设置不同的地图样式/支持各种地图
  • 为时序数据库 IoTDB 底层架构“保驾护航”,来听听新晋 Committer 的贡献心路!
  • onshape
  • RAG(检索增强生成)是什么?为什么很多 AI 产品都用它?
  • 跨域——CORS详解
  • TIA博图的三种视图
  • 智能CRM赋能饮料行业:纷享销客快消品全场景数字化解决方案
  • 调一调
  • 【稳定检索|线上线下参会|马理工主办】第十一届建筑、土木与水利工程国际学术会议(ICACHE 2025)
  • 多版本jdk环境下,指定jdk版本执行jar文件
  • 基于Python+Vue开发的医院门诊预约挂号系统源码+运行
  • 2025.9.8 总结
  • qoj10096 Generating Random Trees
  • PHP 轻松处理千万行数据 内存不爆,服务器不卡
  • BongoCat - 可爱的桌面互动猫咪
  • 读人形机器人07零售行业
  • 2014年11月微软安全更新风险评估与技术解析
  • [Flink] Flink 经典场景:数据流输出到多个Sink
  • 【ChipIntelli 系列】SDK详解4——Makefile 设置 单SDK多工程文件夹实现方法
  • Codeforces Round 1049 (Div. 2)