基于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的封装和简单使用已经介绍完了 ★,°:.☆( ̄▽ ̄)/$:*.°★

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

相关推荐
傻啦嘿哟12 分钟前
Python 办公实战:用 python-docx 自动生成 Word 文档
开发语言·c#
翻滚吧键盘16 分钟前
js代码09
开发语言·javascript·ecmascript
q5673152322 分钟前
R语言初学者爬虫简单模板
开发语言·爬虫·r语言·iphone
万少1 小时前
第五款 HarmonyOS 上架作品 奇趣故事匣 来了
前端·harmonyos·客户端
OpenGL1 小时前
Android targetSdkVersion升级至35(Android15)相关问题
前端
rzl021 小时前
java web5(黑马)
java·开发语言·前端
Amy.Wang1 小时前
前端如何实现电子签名
前端·javascript·html5
时序数据说1 小时前
为什么时序数据库IoTDB选择Java作为开发语言
java·大数据·开发语言·数据库·物联网·时序数据库·iotdb
海天胜景1 小时前
vue3 el-table 行筛选 设置为单选
javascript·vue.js·elementui
今天又在摸鱼1 小时前
Vue3-组件化-Vue核心思想之一
前端·javascript·vue.js