1,前言
最近在做IOT的項(xiàng)目,里面有個(gè)小程序要用到webSocket,借這個(gè)機(jī)會(huì),封裝了一個(gè)uniapp小程序適用的Socket類,包括斷線重連,心跳檢測等等,具體實(shí)現(xiàn)如下。
2,代碼實(shí)現(xiàn)
class webSocketClass {
constructor(url, time) {
this.url = url
this.data = null
this.isCreate = false // WebSocket 是否創(chuàng)建成功
this.isConnect = false // 是否已經(jīng)連接
this.isInitiative = false // 是否主動(dòng)斷開
this.timeoutNumber = time // 心跳檢測間隔
this.heartbeatTimer = null // 心跳檢測定時(shí)器
this.reconnectTimer = null // 斷線重連定時(shí)器
this.socketExamples = null // websocket實(shí)例
this.againTime = 3 // 重連等待時(shí)間(單位秒)
}
// 初始化websocket連接
initSocket() {
const _this = this
this.socketExamples = uni.connectSocket({
url: _this.url,
header: {
'content-type': 'application/json'
},
success: (res) => {
_this.isCreate = true
console.log(res)
},
fail: (rej) => {
console.error(rej)
_this.isCreate = false
}
})
this.createSocket()
}
// 創(chuàng)建websocket連接
createSocket() {
if (this.isCreate) {
console.log('WebSocket 開始初始化')
// 監(jiān)聽 WebSocket 連接打開事件
try {
this.socketExamples.onOpen(() => {
console.log('WebSocket 連接成功')
this.isConnect = true
clearInterval(this.heartbeatTimer)
clearTimeout(this.reconnectTimer)
// 打開心跳檢測
this.heartbeatCheck()
})
// 監(jiān)聽 WebSocket 接受到服務(wù)器的消息事件
this.socketExamples.onMessage((res) => {
console.log('收到消息')
uni.$emit('message', res)
})
// 監(jiān)聽 WebSocket 連接關(guān)閉事件
this.socketExamples.onClose(() => {
console.log('WebSocket 關(guān)閉了')
this.isConnect = false
this.reconnect()
})
// 監(jiān)聽 WebSocket 錯(cuò)誤事件
this.socketExamples.onError((res) => {
console.log('WebSocket 出錯(cuò)了')
console.log(res)
this.isInitiative = false
})
} catch (error) {
console.warn(error)
}
} else {
console.warn('WebSocket 初始化失敗!')
}
}
// 發(fā)送消息
sendMsg(value) {
const param = JSON.stringify(value)
return new Promise((resolve, reject) => {
this.socketExamples.send({
data: param,
success() {
console.log('消息發(fā)送成功')
resolve(true)
},
fail(error) {
console.log('消息發(fā)送失敗')
reject(error)
}
})
})
}
// 開啟心跳檢測
heartbeatCheck() {
console.log('開啟心跳')
this.data = { state: 1, method: 'heartbeat' }
this.heartbeatTimer = setInterval(() => {
this.sendMsg(this.data)
}, this.timeoutNumber * 1000)
}
// 重新連接
reconnect() {
// 停止發(fā)送心跳
clearTimeout(this.reconnectTimer)
clearInterval(this.heartbeatTimer)
// 如果不是人為關(guān)閉的話,進(jìn)行重連
if (!this.isInitiative) {
this.reconnectTimer = setTimeout(() => {
this.initSocket()
}, this.againTime * 1000)
}
}
// 關(guān)閉 WebSocket 連接
closeSocket(reason = '關(guān)閉') {
const _this = this
this.socketExamples.close({
reason,
success() {
_this.data = null
_this.isCreate = false
_this.isConnect = false
_this.isInitiative = true
_this.socketExamples = null
clearInterval(_this.heartbeatTimer)
clearTimeout(_this.reconnectTimer)
console.log('關(guān)閉 WebSocket 成功')
},
fail() {
console.log('關(guān)閉 WebSocket 失敗')
}
})
}
}
export default webSocketClass
3,使用
直接實(shí)例化封裝的socket類,調(diào)用initSocket初始化就行了,當(dāng)收到消息的時(shí)候,會(huì)觸發(fā)全局$emit事件,只需要使用$on監(jiān)聽message事件就行。
3.1,初始化
我這邊在globalData里面定義了socketObj全局變量,在首頁onShow生命周期里面判斷當(dāng)前是否已經(jīng)初始化了socket實(shí)例,再進(jìn)行操作。
home.vue
import WebSocketClass from '../../utils/webSocket'
const app = getApp()
onShow() {
// 如果已登陸,則啟用WebSocket
if (app.globalData.user && app.globalData.user.sToken) {
// 如果已經(jīng)有sockt實(shí)例
if (app.globalData.socketObj) {
// 如果sockt實(shí)例未連接
if (!app.globalData.socketObj.isConnect) {
app.globalData.socketObj.initSocket()
}
} else {
// 如果沒有sockt實(shí)例,則創(chuàng)建
const data = app.globalData.user
const path = `/websocket/notify/${data.userId}`
app.globalData.socketObj = new WebSocketClass(
`${app.globalData.socketUrl}${path}?token=${data.userToken}&refreshToken=${data.sToken}`,
60
)
app.globalData.socketObj.initSocket()
}
}
}
3.2,發(fā)送消息
methods: {
sendMessage() {
const param = { value: '我是一個(gè)消息' }
app.globalData.socketObj.sendMsg(param)
}
}
3.3,接收消息
// 開啟監(jiān)聽
onLoad() {
uni.$on('message', this.getMessage)
},
// 頁面卸載時(shí)取消監(jiān)聽
onUnload() {
uni.$off('message', this.getMessage)
},
methods: {
// 接收到消息的回調(diào)
getMessage(msg) {
console.log(msg)
}
}
3.4,斷線重連
斷線會(huì)自動(dòng)重連。

斷線重連
如果看了覺得有幫助的,我是@鵬多多11997110103,歡迎 點(diǎn)贊 關(guān)注 評(píng)論;
END
PS:在本頁按F12,在console中輸入document.querySelectorAll('._2VdqdF')[0].click(),有驚喜哦
往期文章
- 助你上手Vue3全家桶之Vue3教程
- 助你上手Vue3全家桶之VueX4教程
- 助你上手Vue3全家桶之Vue3教程
- 超詳細(xì)!Vuex手把手教程
- 使用nvm管理node.js版本以及更換npm淘寶鏡像源
- 超詳細(xì)!Vue-Router手把手教程
- vue中利用.env文件存儲(chǔ)全局環(huán)境變量,以及配置vue啟動(dòng)和打包命令
- 微信小程序?qū)崿F(xiàn)搜索關(guān)鍵詞高亮
個(gè)人主頁