vue3.0中使用websocket,封装到公共方法的实现

目录
  • 使用websocket,封装到公共方法
  • vue中封装websocket问题
    • 1.在untils文件夹下新建socket_service.js
    • 2.在main.js里引用
    • 2.在组件里调用$socket

使用websocket,封装到公共方法

首先创建一个socket.ts文件封装公共方法

/*
 * @Descripttion: 封装socket方法
 * @version:
 * @Date: 2021-08-06 11:14:39
 * @LastEditTime: 2021-10-26 14:06:34
 */
import i18n from '@/locales'
import store from '@/store'
import { ElMessage } from 'element-plus'
import { Base64 } from 'js-base64'
const language = store.state.users.language // 当前用户信息,后台配置
const token = store.state.users.authorization // 获取验证信息,后台配置
interface socket {
	websocket: any
	connectURL: string
	socket_open: boolean
	hearbeat_timer: any
	hearbeat_interval: number
	is_reonnect: boolean
	reconnect_count: number
	reconnect_current: number
	ronnect_number: number
	reconnect_timer: any
	reconnect_interval: number
	init: (receiveMessage: Function | null) => any
	receive: (message: any) => void
	heartbeat: () => void
	send: (data: any, callback?: any) => void
	close: () => void
	reconnect: () => void
}
const socket: socket = {
	websocket: null,
	connectURL: `${process.env.VUE_APP_SOCEKT_URL}/websocket/v1/${language}/${token}`,
	// 开启标识
	socket_open: false,
	// 心跳timer
	hearbeat_timer: null,
	// 心跳发送频率
	hearbeat_interval: 45000,
	// 是否自动重连
	is_reonnect: true,
	// 重连次数
	reconnect_count: 3,
	// 已发起重连次数
	reconnect_current: 1,
	// 网络错误提示此时
	ronnect_number: 0,
	// 重连timer
	reconnect_timer: null,
	// 重连频率
	reconnect_interval: 5000,
	init: (receiveMessage: Function | null) => {
		if (!('WebSocket' in window)) {
			ElMessage.warning('浏览器不支持WebSocket')
			return null
		}
		// 已经创建过连接不再重复创建
		// if (socket.websocket) {
		//   return socket.websocket
		// }
		socket.websocket = new WebSocket(socket.connectURL)
		socket.websocket.onmessage = (e: any) => {
			if (receiveMessage) {
				receiveMessage(e)
			}
		}
		socket.websocket.onclose = (e: any) => {
			clearInterval(socket.hearbeat_interval)
			socket.socket_open = false
			// 需要重新连接
			if (socket.is_reonnect) {
				socket.reconnect_timer = setTimeout(() => {
					// 超过重连次数
					if (socket.reconnect_current > socket.reconnect_count) {
						clearTimeout(socket.reconnect_timer)
						socket.is_reonnect = false
						return
					}
					// 记录重连次数
					socket.reconnect_current++
					socket.reconnect()
				}, socket.reconnect_interval)
			}
		}
		// 连接成功
		socket.websocket.onopen = function() {
			socket.socket_open = true
			socket.is_reonnect = true
			// 开启心跳
			// socket.heartbeat()
		}
		// 连接发生错误
		socket.websocket.onerror = function() {}
	},
	send: (data, callback = null) => {
		// 开启状态直接发送
		if (socket.websocket.readyState === socket.websocket.OPEN) {
			socket.websocket.send(JSON.stringify(data))
			if (callback) {
				callback()
			}
			// 正在开启状态,则等待1s后重新调用
		} else {
			clearInterval(socket.hearbeat_timer)
			if (socket.ronnect_number < 1) {
				ElMessage({
					type: 'error',
					message: i18n.global.t('chat.unopen'),
					duration: 0,
				})
			}
			socket.ronnect_number++
		}
	},
	receive: (message: any) => {
		let params = Base64.decode(JSON.parse(message.data).data)
		params = JSON.parse(params)
		return params
	},
	heartbeat: () => {
		if (socket.hearbeat_timer) {
			clearInterval(socket.hearbeat_timer)
		}
		socket.hearbeat_timer = setInterval(() => {
			let data = {
				languageId: store.state.users.language,
				authToken: store.state.users.authorization,
				content: 'ping',
			}
			var sendDara = {
				encryption_type: 'base64',
				data: Base64.encode(JSON.stringify(data)),
			}
			socket.send(sendDara)
		}, socket.hearbeat_interval)
	},
	close: () => {
		clearInterval(socket.hearbeat_interval)
		socket.is_reonnect = false
		socket.websocket.close()
	},
	/**
	 * 重新连接
	 */
	reconnect: () => {
		if (socket.websocket && !socket.is_reonnect) {
			socket.close()
		}
		socket.init(null)
	},
}
export default socket

然后在聊天组件中引入

import socket from '@/utils/socket'

在挂载的生命周期放方法里面初始化socket

socket.init(methods.receiveMessage)

在这里 我们为websocket的onmessage方法传入了一个函数作为参数,这样的话我们在组件里面实现一个消息处理的方法

	// 消息接收
			receiveMessage(message: any) {
				const param = JSON.parse(Base64.decode(JSON.parse(message.data).data))
				// 处理 赋值问题
				const params = JSON.parse(JSON.stringify(param))
				if (params) {
					switch (params.message) {
						case 'scheduleListFeedBack':
							break
						case 'onMessage':
							// 地磁获取消息列表 正则替换给过来的编码

							break
					}
				}
			},

这样在onmessage里面的消息内容,我们可以通过方法传递回来,就可以在页面里面使用,其中的scheduleListFeedBack、onMessage是和后端定义的websocket的特定消息响应类型标识,可以拿到我们所需要的消息内容,进行逻辑处理。

这个方法是在socket.ts里面预先定义好的

socket.websocket.onmessage = (e: any) => {
	if (receiveMessage) {
			receiveMessage(e)
		}
}

vue中封装websocket问题

每个组件页面都用到websocket,可以讲websocket封装起来,用到的组件页面一调用就好。

1.在untils文件夹下新建socket_service.js

export default class SocketService {
  static instance = null
  static get Instance () {
    if (!this.instance) {
      this.instance = new SocketService()
    }
    return this.instance
  }
  
  ws = null
  //存储回调函数
  callBackMapping = {}
  //标识是否连接成功
  connected = false
  //记录重试的次数
  sendRetryCount = 0
  //记录重新连接的次数
  reconnectCount = 0
  connect () {
    if (!window.WebSocket) {
      return console.log("您的浏览器不支持websocket!")
    }
    this.ws = new WebSocket('ws://192.168.0.88:8088')
    //连接服务端成功事件
    this.ws.onopen = ()=> {
      console.log("连接服务端成功")
      this.connected = true
      this.reconnectCount = 0
    }
    //连接服务端失败事件
    this.ws.onclose = ()=> {
      console.log("连接服务端失败")
      this.connected = false
      this.reconnectCount++
      setTimeout(()=>{
        this.connect()
      },this.reconnectCount*500)
    }
    //从服务端获取数据
    this.ws.onmessage = (msg)=> {
      console.log("从服务端获取到的数据" + msg.data)
      const recvData = JSON.parse(msg.data)
      const socketType = recvData.socketType
      if (this.callBackMapping[socketType]) {
        const action = recvData.action
        if (action === 'getData') {
          const realData = JSON.parse(recvData.data)
          this.callBackMapping[socketType].call(this, realData)
        }
      }
    }
  }
  //回调函数的注册
  registerCallBack (socketType, callBack) {
    this.callBackMapping[socketType] = callBack
  }
  //取消回调函数
  unRegisterCallBack (socketType) {
    this.callBackMapping[socketType] = null
  }
  send(data) {
    if (this.connected) {
      this.sendRetryCount = 0
      this.ws.send(JSON.stringify(data))
    } else {
      this.sendRetryCount++
      setTimeout(()=>{
        this.ws.send(JSON.stringify(data))
      },this.sendRetryCount*500)
    }
  } 
}

2.在main.js里引用

import SocketService from '@/utils/socket_service'
SocketService.Instance.connect()
Vue.prototype.$socket = SocketService.Instance
Vue.prototype.wsPath = 'ws://192.168.0.88:8088/'     // websocket路径

2.在组件里调用$socket

mounted() {
     this.$socket.send({
        action:'getData',
        socketType:'productivity',
        chartName:'product',
        value:''
      })
    },
created() {
      this.$socket.registerCallBack('productivity',this.getWsData)
    },
destroyed() {
     this.$socket.unRegisterCallBack('productivity')
    },
methods:{
    getWsData (ret) {
        console.log('websocket接收到的值', event.ret)
        console.log(ret);
        this.cdata.category.forEach(item => {
          if (dataRec.materialClassifyName === item.materialClassifyName) {
            item.rate = dataRec.rate
          }
        })
      },
    }

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Vue项目使用Websocket大文件FileReader()切片上传实例

    目录 使用技术 upfile.js文件 新增需求:对上传文件流进行加密,并传给后端做验证 还是在upfile.js文件(也可以单独放一个文件) 大文件上传,本地1.3G文件不到一分钟上传完毕 使用技术 Vue框架 WebSocket双向传输 FileReader读取文件 封装的WebSocket请求文件上传方法,目前只支持单文件上传,有研究出来多文件上传,记得评论哦 upfile.js文件 //file.slice(起始字节,终止字节)与FileReader实现文件切片读取 function P

  • vue项目使用websocket连接问题及解决

    目录 vue使用websocket连接 前景 解决过程 vue2全局使用websocket记录 新建ws模块文件 在main.js中引用ws模块文件 App.vue挂载时再次连接服务器并且接收消息 vue使用websocket连接 前景 公司做一个包含websocket的项目,我用的是vue做的,开始只有一个组件的要求demo,就将websocket的配置直接放在组件方法中,组件挂载时直接初始化ws,但是后续组件增加,开始出现多个websocket链接的情况,是不允许的. 刚开始的做法是将web

  • vue3+ts+Vuex中使用websocket协议方式

    目录 vue3+ts+Vuex使用websocket协议 在stroe中 vue3中 vue封装websocket 封装的socket.js文件内容 使用方法 vue3+ts+Vuex使用websocket协议 本文作者使用的是ts+vue3的setup语法糖,大家注意使用的vue版本! 在stroe中 import { createStore } from 'vuex' import { stateInt } from '../interface/storeInterface' const s

  • vue使用websocket概念及示例

    目录 概念部分: 使用示例 概念部分: 1,WebSocket 是 HTML5 提供的 TCP 连接上进行全双工通讯的协议.一次握手之后,服务器和客户端可以互相主动通信,双向传输数据. 2,浏览器想服务器发送请求,建立连接之后,可通过send()方法想服务器发送数据,并通过message事件接受服务器返回的数据. 使用示例 <script> export default { mounted() { this.connectWebsocket(); }, methods: { connectWe

  • Vue websocket封装实现方法详解

    目录 1.封装的ws.js文件 2.使用方法 1.封装的ws.js文件 let global_callback = null let socket = '' // 存储 WebSocket 连接. let timeoutObj = null // 心跳定时器 let serverTimoutObj = null // 服务超时定时关闭 let lockReconnect = false // 是否真正建立了连接 let timeoutnum = null // 重新连接的定时器, 没连接上会一直

  • vue3.0中使用websocket,封装到公共方法的实现

    目录 使用websocket,封装到公共方法 vue中封装websocket问题 1.在untils文件夹下新建socket_service.js 2.在main.js里引用 2.在组件里调用$socket 使用websocket,封装到公共方法 首先创建一个socket.ts文件封装公共方法 /* * @Descripttion: 封装socket方法 * @version: * @Date: 2021-08-06 11:14:39 * @LastEditTime: 2021-10-26 14

  • 如何在vue3.0+中使用tinymce及实现多图上传文件上传公式编辑功能

    相关文档 本文部分内容借鉴: https://www.cnblogs.com/zhongchao666/p/11142537.html tinymce中文文档: http://tinymce.ax-z.cn/ 安装tinymce 1.安装相关依赖 yarn add tinymce || npm install tinymce -S yarn add @tinymce/tinymce-vue || npm install @tinymce/tinymce-vue -S 2.汉化编辑器前往此地址下载

  • vue3.0中setup的两种用法实例

    目录 前言 一.setup函数的特性以及作用 二.setup函数的注意点: 用法1:结合ref使用 用法2:代码分割 总结 前言 这篇文章主要介绍了vue3.0中setup使用,本文通过两种用法给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下 什么是setup setup是vue3新增的生命周期函数,setup的加入就是为了让vue3使用组合式API(Composition API).使用组合式API更符合大型项目的开发,通过setup可以将该部分抽离成函数,

  • vue3.0中的双向数据绑定方法及优缺点

    熟悉vue的人都知道在vue2.x之前都是使用object.defineProperty来实现双向数据绑定的 而在vue3.0中这个方法被取代了 1. 为什么要替换Object.defineProperty 替换不是因为不好,是因为有更好的方法使用效率更高 Object.defineProperty的缺点: 1. 在Vue中,Object.defineProperty无法监控到数组下标的变化, 导致直接通过数组的下标给数组设置值,不能实时响应. push() pop() shift() unsh

  • Vue3.0中的monorepo管理模式的实现

    前言 前段时间9月21日参加了在成都举办的第五届FEDAY, 印象比较深刻的是白鹭引擎首席架构师@王泽分享的<框架开发中的基础设施搭建>,提到了在下一代白鹭引擎中使用到monorepo模式,以用来管理多个模块,协调各个模块之间的依赖更新. 正好在国庆期间10月5日尤大公开了vue3.0已完成的源码,也是采用了monorepo管理模式,看来monorepo确实有其独到的优势,再加上以前在项目中遇到过相关的痛点,所以深入地了解了一下这种模式,本文将基于vue3.0讨论如何通过monorepo模式来

  • vue3.0中setup使用(两种用法)

    一.setup函数的特性以及作用 可以确定的是 Vue3.0 是兼容 Vue2.x 版本的 也就是说我们再日常工作中 可以在 Vue3 中使用 Vue2.x 的相关语法 但是当你真正开始使用 Vue3 写项目时 你会发现他比 Vue2.x 方便的多 Vue3 的一大特性函数 ---- setup 1.setup函数是处于 生命周期函数 beforeCreate 和 Created 两个钩子函数之间的函数 也就说在 setup函数中是无法 使用 data 和 methods 中的数据和方法的 2.

  • vue3.0中友好使用antdv示例详解

    前言 随着我们vue3.0的出现,我们的ui组件库也有了一些变化,像我们的旧版的element-ui已经不能在vue3.0中使用了,如果要使用element的话需要使用最新版的element-plus,由于发现它并不太好用,因此我选择了Ant Design Vue. 如果我们以前经常使用antd的话,我们使用起来这个上手会非常方便. 在vue3.0中引入我们的antdv 1.首先使用我们的vue/cli创建vue3.0项目并使用less 2. 在vue3.0中使用的话我们需要安装 ant-des

  • vue3.0中使用element的完整步骤

    前言: 在vue3.0中使用element框架,因为element是支持vue2.0的,他推出的支持vue3.0的版本叫 element-plus 官网入口:点我进入 一.个人遇到的问题与解决办法: 遇到的问题: 我直接用cnpm  i element-plus -S 装的版本,不知道为啥,一直报错 图1,版本型号 图2 ,我的代码中使用图3 解决办法: 我把package.json中的element-plus的版本更换成    下面这句话,解决了问题(是否为最新版本问题,还在求证中) "ele

  • Vue3.0中Ref与Reactive的区别示例详析

    目录 Ref与Reactive Ref Reactive Ref与Reactive的区别 shallowRef 与shallowReactive toRaw ---只修改数据不渲染页面 markRaw --- 不追踪数据 toRef --- 跟数据源关联 不修改UI toRefs ---设置多个toRef属性值 customRef ---自定义一个ref ref 捆绑页面的标签 总结 Ref与Reactive Ref Ref 用来创建基础类型的响应式数据,模板默认调用value显示数据.方法中修

  • 快速掌握Vue3.0中如何上手Vuex状态管理

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化.Vuex 也集成到 Vue 的官方调试工具 devtools,提供了诸如零配置的 time-travel 调试.状态快照导入导出等高级调试功能. 如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的.确实是如此--如果您的应用够简单,您最好不要使用 Vuex.一个简单的 store 模式就足够您所需了.但是,如果您需要构建一个中大型

随机推荐