最近在做一个赛事的需求,需要使用实时通讯实现房间内交换位置,转让房主,踢出房间等操作
记录一下基于uniapp中websocket的封装和使用
话不投机半句多(少bb),准备动手,准备动手
类名: WebsocketTask
私有属性:
#heartbeatInterval
: 心跳定时器。#callback
: 回调函数。#websocketStatus
: WebSocket 连接状态。#isClosed
: 是否主动关闭。 /** 心跳定时器 */
#heartbeatInterval = null
/** 回调函数 */
#callback = null
/** ws状态 */
#websocketStatus = false
/** 是否主动关闭 */
#isClosed = false
参数:
url
: WebSocket 服务器地址。interval
: 心跳间隔时间。功能:
url
和 intervalTime
。 constructor (url, interval) {
this.url = url
this.intervalTime = interval
// 实例化时立即连接ws。根据需求启用
// try {
// return this.initWebsocket()
// } catch (e) {
// this.#websocketStatus = false
// this.reconnect()
// }
}
initWebsocket
功能: 初始化 WebSocket 连接。
步骤:
uni.connectSocket
创建 WebSocket 连接。onOpen
事件,连接成功后启动心跳定时器并设置状态。onMessage
事件,处理接收到的消息。onError
事件,处理连接错误。onClose
事件,处理连接关闭,并在非主动关闭时尝试重连。#startHeartbeat
功能: 启动心跳定时器。
步骤:
setInterval
定期发送心跳消息 { cmd: 'ping' }
。 /** 开始心跳 */
#startHeartbeat() {
this.#heartbeatInterval = setInterval(() => {
this.sendMessage({
cmd: 'ping'
})
}, this.intervalTime)
}
sendMessage
参数:
data
: 要发送的消息内容。功能: 发送消息。
步骤:
seq
。 /**
* 发送消息
* @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)
})
}
setCallback
参数:
cb
: 回调函数。功能: 设置消息接收的回调函数。
/** 设置回调 */
setCallback(cb) {
this.#callback = cb
}
reconnect
功能: 重新连接 WebSocket。
步骤:
reconnect() {
clearInterval(this.#heartbeatInterval)
if(!this.#websocketStatus) {
setTimeout(() => {
this.initWebsocket()
}, 3000);
}
}
disconnect
功能: 主动断开 WebSocket 连接。
步骤:
uni.closeSocket
关闭连接。 /** 主动断开连接 */
disconnect() {
uni.closeSocket()
this.#websocketStatus = false
this.#isClosed = true
clearInterval(this.#heartbeatInterval)
}
}
至此,WebsocketTask的类已经封装好了,里面包括了websocket连接、消息发送、心跳机制和重连。接着就是websocket的使用了。
WebsocketTask
实例: 实例化 WebsocketTask
类,创建一个具体的 WebSocket 连接对象。Vue
原型: 为了避免在切换页面的时候导致ws连接断开,可以将ws实例化挂载至vue全局,使得在整个应用中可以通过 this.$websocket
访问到这个 WebSocket 实例,方便管理和使用 WebSocket 连接。//main.js
Vue.prototype.$websocket = new WebsocketTask('ws://test.com', 3000)
const app = new Vue({
i18n,
...App
})
app.$mount()
//demo.vue
onLoad(){
this.$websocket.initWebsocket()
//设置回调
}
//demo.vue
onLoad(){
this.$websocket.setCallback((msg)=>{
//收到消息时的回调函数
this.decodeWsMsg(msg)
})
//设置回调
}
methods: {
//处理ws消息
decodeWsMsg(msg) {
}
}
//demo.vue
methods: {
sendMsg(msg) {
this.$websocket.sendMessage({value: 'hello, 我是郭德纲'})
}
}
//demo.vue
onUnload() {
// 主动断开连接
this.$websocket.disconnect()
},
WebsocketTask
类封装了 WebSocket 的连接、消息发送、心跳机制和重连逻辑。uni.connectSocket
进行 WebSocket 连接,适用于 Uni-app。WebSocket
实例挂载到vue
全局this.$websocket
访问到这个 WebSocket 实例,调用实例的方法进行连接、消息发送、处理消息、断开连接、重连等操作。uniapp-websocket
uniapp-SocketTask
至此,WebSocket的封装和简单使用已经介绍完了 ★,°:.☆( ̄▽ ̄)/$:*.°★
下次再见!(●’◡’●)