websocket 封裝
1. 將websocket.js放入任意文件夾中
let isSocketClose = false; // 是否關(guān)閉socket
let reconnectCount = 5; // 重連次數(shù)
let heartbeatInterval = ""; // 心跳定時器
let socketTask = null; // websocket對象
let againTimer = null; //斷線重連定時器
let url = null;
let onReFn = null;
let onSucFn = null;
let onErrFn = null;
/**
* sockeUrl:websocet的地址
* onReceive:消息監(jiān)聽的回調(diào)
* onErrorEvent:拋出錯誤的回調(diào)枪萄,且彈窗連接失敗的提示框
* onErrorSucceed:拋出成功回調(diào)问慎,主要用于隱藏連接失敗的提示框
* */
const sokcet = (sockeUrl, onReceive, onErrorEvent, onErrorSucceed) => {
url = sockeUrl;
onReFn = onReceive;
onErrFn = onErrorEvent;
onSucFn = onErrorSucceed;
isSocketClose = false;
//判斷是否有websocet對象酌壕,有的話清空
if (socketTask) {
socketTask.close();
socketTask = null;
clearInterval(heartbeatInterval);
}
//WebSocket的地址
// 【非常重要】必須確保你的服務(wù)器是成功的,如果是手機測試千萬別使用ws://127.0.0.1:9099【特別容易犯的錯誤】
let url = sockeUrl
// 連接
socketTask = uni.connectSocket({
url: url,
success(data) {
console.log("websocket連接成功");
clearInterval(againTimer) //斷線重連定時器
},
fail: (err) => {
console.log(url)
console.log("報錯", err);
}
});
// 連接打開
socketTask.onOpen((res) => {
console.log('WebSocket打開');
clearInterval(againTimer) //斷線重連定時器
onErrorSucceed({
isShow: false
}) // 用于提示框的隱藏
heartbeatInterval && clearInterval(heartbeatInterval);
// 10秒發(fā)送一次心跳
heartbeatInterval = setInterval(() => {
sendMsg('心跳ing')
}, 1000 * 5)
})
// 監(jiān)聽連接失敗
socketTask.onError((err) => {
console.log('WebSocket連接打開失敗拼窥,請檢查', err);
//停止發(fā)送心跳
clearInterval(heartbeatInterval)
//如果不是人為關(guān)閉的話汪诉,進(jìn)行重連
if (!isSocketClose) {
reconnect(url, onErrorEvent)
}
})
// // 監(jiān)聽連接關(guān)閉 -
socketTask.onClose((e) => {
console.log('WebSocket連接關(guān)閉长踊!');
clearInterval(heartbeatInterval)
if (!isSocketClose) {
reconnect(url, onErrorEvent)
}
})
// 監(jiān)聽收到信息
socketTask.onMessage((res) => {
uni.hideLoading()
console.log(res, 'res監(jiān)聽收到信息')
let serverData = res.data
//與后端規(guī)定好返回值分別代表什么棚潦,寫業(yè)務(wù)邏輯
serverData && onReceive(serverData);
});
}
const reconnect = (url, onErrorEvent) => {
console.log('進(jìn)入斷線重連', isSocketClose);
clearInterval(againTimer) //斷線重連定時器
clearInterval(heartbeatInterval);
socketTask && socketTask.close(); // 確保已經(jīng)關(guān)閉后再重新打開
socketTask = null;
onErrorEvent({
isShow: true,
messge: '掃描頭服務(wù)正在連接...'
})
// 連接 重新調(diào)用創(chuàng)建websocet方法
againTimer = setInterval(() => {
sokcet(url, onReFn, onErrFn, onSucFn)
console.log('在重新連接中...');
}, 1000 * 5)
}
const sendMsg = (msg) => { //向后端發(fā)送命令
msg = JSON.stringify(msg)
try {
//通過 WebSocket 連接發(fā)送數(shù)據(jù)
socketTask.send({
data: msg
});
} catch (e) {
if (isSocketClose) {
return
} else {
reconnect(url, onErrFn)
}
}
}
// 關(guān)閉websocket【必須在實例銷毀之前關(guān)閉,否則會是underfined錯誤】beforeDestroy() {websocetObj.stop();}
const stop = () => {
isSocketClose = true
clearInterval(heartbeatInterval);
clearInterval(againTimer) //斷線重連定時器
socketTask.close(); // 確保已經(jīng)關(guān)閉后再重新打開
socketTask = null;
}
const $debounce = function(fn, wait) {
let timer = null;
return function() {
if (timer !== null) {
clearTimeout(timer);
}
timer = setTimeout(fn, wait);
}
}
export const websocetObj = {
sokcet,
stop,
sendMsg
};
2. 在需要引入的頁面中導(dǎo)入websocket.js
<template>
</template>
<script>
import {websocetObj} from '@/utils/websock.js';
export default {
onLoad() {
websocetObj.sokcet('ws://192.168.xx.xx:xxx/ws?cid=' + this.cid + '&ip=' + this.IP + '&token=' + this.token, this.getWebsocetData, this.getWebsocetError, this.onErrorSucceed) //請求地址
},
methods: {
//websocet函數(shù)回調(diào):返回監(jiān)聽的數(shù)據(jù)
getWebsocetData(val) {
console.log(val, '函數(shù)回調(diào)'); // 接收參數(shù)
this.plotterItem.push(val)
},
//websocet函數(shù)拋錯: 返回錯誤信息 用于用戶提示
getWebsocetError(err) {
this.socketShow = err.isShow;
this.webtext = err.messge;
console.log('websocet函數(shù)拋錯', this.socketShow);
},
//websocet函數(shù)成功進(jìn)入: 監(jiān)聽連接狀態(tài)儡率,在失敗的時候彈窗提示侯繁,具體需求看自身情況
onErrorSucceed(val) {
this.socketShow = val.isShow;
console.log(val);
console.log('websocet函數(shù)成功進(jìn)入', this.socketShow);
},
}
}
</script>
<style>
</style>