基于uniapp使用websocket进行实时通讯

前言

最近在做一个赛事的需求,需要使用实时通讯实现房间内交换位置,转让房主,踢出房间等操作

记录一下基于uniapp中websocket的封装和使用

话不投机半句多(少bb),准备动手,准备动手

ws方法封装

1. 类定义
  • 类名 : WebsocketTask

  • 私有属性:

    • #heartbeatInterval: 心跳定时器。
    • #callback: 回调函数。
    • #websocketStatus: WebSocket 连接状态。
    • #isClosed: 是否主动关闭。
js 复制代码
	/** 心跳定时器 */
	#heartbeatInterval = null
	/** 回调函数 */
	#callback = null
	/** ws状态 */
	#websocketStatus = false
	/** 是否主动关闭 */
	#isClosed = false
2. 构造函数
  • 参数:

    • url: WebSocket 服务器地址。
    • interval: 心跳间隔时间。
  • 功能:

    • 初始化 urlintervalTime
    • 注释掉的代码块用于在实例化时立即连接 WebSocket,并在连接失败时尝试重连。
js 复制代码
	constructor (url, interval) {
		this.url = url
		this.intervalTime = interval
		
		// 实例化时立即连接ws。根据需求启用
		// try {
		// 	return this.initWebsocket()
		// } catch (e) {
		// 	this.#websocketStatus = false
		// 	this.reconnect()
		// }
	}
3. 方法
3.1 initWebsocket
  • 功能: 初始化 WebSocket 连接。

  • 步骤:

    • 使用 uni.connectSocket 创建 WebSocket 连接。
    • 监听 onOpen 事件,连接成功后启动心跳定时器并设置状态。
    • 监听 onMessage 事件,处理接收到的消息。
    • 监听 onError 事件,处理连接错误。
    • 监听 onClose 事件,处理连接关闭,并在非主动关闭时尝试重连。
3.2 #startHeartbeat
  • 功能: 启动心跳定时器。

  • 步骤:

    • 使用 setInterval 定期发送心跳消息 { cmd: 'ping' }
js 复制代码
	/** 开始心跳 */
	#startHeartbeat() {
		this.#heartbeatInterval = setInterval(() => {
			this.sendMessage({
				cmd: 'ping'
			})
		}, this.intervalTime)
	}
3.3 sendMessage
  • 参数:

    • data: 要发送的消息内容。
  • 功能: 发送消息。

  • 步骤:

    • 生成消息序列号 seq
    • 如果消息不是心跳或退出命令且 WebSocket 未就绪,则稍后重试。
    • 发送消息并记录日志。
js 复制代码
	/**
	 * 发送消息
	 * @param {*} data 消息内容
	 */
	sendMessage (data) {
		let seq = Date.now().toString()
		if (data.cmd !== 'ping' && data.cmd !== 'exit') {
			// 未就绪时稍后重试
			if (!this.#websocketStatus) {
				console.warn(' [Websocket] 未就绪', JSON.stringify(data))
				return setTimeout(() => {
					this.sendMessage({...data, seq})
				}, this.intervalTime);
			}
			console.log('%c [Websocket] ', 'background: #2888D9;', '发送消息:', JSON.stringify(data))
		}
		this.socketTask.send({
			data: JSON.stringify(data)
		})
	}
3.4 setCallback
  • 参数:

    • cb: 回调函数。
  • 功能: 设置消息接收的回调函数。

js 复制代码
	/** 设置回调 */
	setCallback(cb) {
		this.#callback = cb
	}
	
3.5 reconnect
  • 功能: 重新连接 WebSocket。

  • 步骤:

    • 清除心跳定时器。
    • 如果 WebSocket 未就绪,则延迟 3 秒后重新初始化连接。
js 复制代码
	reconnect() {
		clearInterval(this.#heartbeatInterval)
		if(!this.#websocketStatus) {
			setTimeout(() => {
				this.initWebsocket()
			}, 3000);
		}
	}
3.6 disconnect
  • 功能: 主动断开 WebSocket 连接。

  • 步骤:

    • 使用 uni.closeSocket 关闭连接。
    • 设置状态为未连接和已关闭。
    • 清除心跳定时器。
js 复制代码
	/** 主动断开连接 */
	disconnect() {
            uni.closeSocket()
            this.#websocketStatus = false
            this.#isClosed = true
            clearInterval(this.#heartbeatInterval)
	}
}

至此,WebsocketTask的类已经封装好了,里面包括了websocket连接、消息发送、心跳机制和重连。接着就是websocket的使用了。

把ws实例挂载到全局:

  • 创建 WebsocketTask 实例: 实例化 WebsocketTask 类,创建一个具体的 WebSocket 连接对象。
  • 挂载到 Vue 原型: 为了避免在切换页面的时候导致ws连接断开,可以将ws实例化挂载至vue全局,使得在整个应用中可以通过 this.$websocket 访问到这个 WebSocket 实例,方便管理和使用 WebSocket 连接。
js 复制代码
//main.js
Vue.prototype.$websocket = new WebsocketTask('ws://test.com', 3000)
const app = new Vue({
  i18n,
  ...App
})
app.$mount()

页面中的使用

  • 初始化ws:
js 复制代码
//demo.vue
onLoad(){
   this.$websocket.initWebsocket()
   //设置回调
}
  • 设置回调:
js 复制代码
//demo.vue
onLoad(){
   this.$websocket.setCallback((msg)=>{
       //收到消息时的回调函数
       this.decodeWsMsg(msg)
   })
   //设置回调
}
methods: {
   //处理ws消息
   decodeWsMsg(msg) {
   }
}
  • 发送信息:
js 复制代码
 //demo.vue
methods: {
    sendMsg(msg) {
        this.$websocket.sendMessage({value: 'hello, 我是郭德纲'})
    }
}
  • 断开ws:
js 复制代码
 //demo.vue
 onUnload() {
    // 主动断开连接
    this.$websocket.disconnect()
 },

总结

  • WebsocketTask 类封装了 WebSocket 的连接、消息发送、心跳机制和重连逻辑。
  • 提供了回调函数设置和主动断开连接的方法。
  • 使用 uni.connectSocket 进行 WebSocket 连接,适用于 Uni-app。
  • WebSocket实例挂载到vue全局
  • 在具体页面中使用this.$websocket 访问到这个 WebSocket 实例,调用实例的方法进行连接、消息发送、处理消息、断开连接、重连等操作。

参考文档:

uniapp-websocket

uniapp-SocketTask


至此,WebSocket的封装和简单使用已经介绍完了 ★,°:.☆( ̄▽ ̄)/$:*.°★

下次再见!(●'◡'●)

相关推荐
m0_748235956 分钟前
前端三件套-css
前端·css
A Runner for leave10 分钟前
Java基本概念6-JVM2
java·开发语言
鸿蒙自习室10 分钟前
鸿蒙开发——关系型数据库的基本使用与跨设备同步
前端·数据库·华为·harmonyos·鸿蒙
抓哇FullStack-Junior24 分钟前
设计模式——代理模式
java·开发语言·设计模式·代理模式
Oneforlove_twoforjob30 分钟前
【Java基础面试题026】Java中的String、StringBuffer和StringBuilder的区别是什么?
java·开发语言·面试
孤寂大仙v34 分钟前
【C++】智能指针详解
java·开发语言·c++
天天进步201541 分钟前
Web应用中的CSRF防护机制
前端·网络·csrf
lzhdim42 分钟前
2、C#基于.net framework的应用开发实战编程 - 设计(二、二) - 编程手把手系列文章...
开发语言·c#·.net
山山而川粤1 小时前
时间管理系统|Java|SSM|JSP|
java·开发语言·后端·学习·mysql
冒泡P1 小时前
【Lua热更新】上篇
开发语言·数据结构·unity·c#·游戏引擎·lua