看了市場上已有的ws 庫都不是很想要的郭卫,因?yàn)槎紱]有自動重連功能砍聊,所以自己開發(fā)了一個,不定期維護(hù)代碼贰军。
使用方法在store里面建立以一個新的模塊引入
包含了斷線重連玻蝌,心跳檢測等
import config from '@/config/config.js'
export default {
state:{
//鏈接是否打開了
IsOpen:false,
// SocketTask
SocketTask:false,
//綁定的fd
bindFd:null,
// 當(dāng)前聊天對象(進(jìn)入聊天頁面獲刃分狻)
Network:true,
//斷線重連定時器
timer:null,
//心跳間隔
timeout:10000,
//心跳事件
interval:null,
// 當(dāng)前重連次數(shù)
connectNum : 0,
//當(dāng)前聊天場景
CurrentToUser:{
id:0, // 用戶ID,或者群聊ID
name:"",//type=chat,就是昵稱,group,就是群聊名稱
avatar:"",
type:"chat",//group 群聊,
},
noreadnum:0,//當(dāng)前總未讀消息數(shù)量,最大99
},
mutations:{
// 關(guān)閉連接
wsClose(state){
if (state.IsOpen){
state.IsOpen = false;
state.SocketTask.close();
}
},
set_IsOpen(state,bool){
state.IsOpen = bool
},
set_SocketTask(state,object){
state.SocketTask = object
},
set_bindFd(state,fd){
state.bindFd = fd
},
set_Network(state,bool){
state.Network = bool
},
set_timer(state,timer){
state.timer = timer
},
set_timeout(state,timeout){
state.timeout = timeout
},
set_interval(state,obj){
state.interval = obj
},
set_connectNum(state,num){
state.connectNum = num
},
set_CurrentToUser(state,obj){
state.CurrentToUser = obj
},
set_noreadnum(state,num){
state.noreadnum = num
}
},
actions:{
initWs({ commit, state }){
console.log('檢查是否已鏈接')
if(state.IsOpen) return; // 防止重復(fù)連接
//檢查網(wǎng)絡(luò)是否可用
const _this = this;
uni.getNetworkType({
success(result) {
console.log(result)
if (result.networkType != 'none') {
// 連接
console.log('開始ws鏈接')
const wsurl = config.websocketUrl +'?token=' + uni.getStorageSync('token');
state.SocketTask = uni.connectSocket({
url:wsurl,
complete: (e)=> {
},
});
if (!state.SocketTask) return;
// 監(jiān)聽開啟
state.SocketTask.onOpen(()=>{
console.log('鏈接成功')
// 將連接狀態(tài)設(shè)為已連接
state.IsOpen = true;
//開啟心跳
state.interval=setInterval(() => {
//發(fā)送心跳
uni.sendSocketMessage({
data : 'PING',
fail:function(e){
console.log('心跳發(fā)送失敗了 ...執(zhí)行重連');
uni.showToast({
title: '正在嘗試重新鏈接第'+state.connectNum+'次',
icon:"none",
});
state.IsOpen = false;
//執(zhí)行重連
//_this.dispatch('reConnect')
_this.dispatch('reConnect');
},
});
}, state.timeout);
});
// 監(jiān)聽信息
state.SocketTask.onMessage((e)=>{
console.log(e.data);
if(e.data !=='PONG'){
// 字符串轉(zhuǎn)json
let res = JSON.parse(e.data);
console.log(res);
//根據(jù)消息類型分發(fā)事件
switch(res.msg_type){
case 'close':
if (state.IsOpen){
state.SocketTask.close();
}
break;
case 'bindResult':
state.bindFd = res.fd;
break;
case 'chat':
//聊天消息
//根據(jù)消息內(nèi)容處理業(yè)務(wù)
// 總未讀數(shù)+1
if (state.CurrentToUser.id !== res.from_id) {
if(state.noreadnum < 99){
noreadnum +=1;
}
}
break;
}
}
})
// 監(jiān)聽關(guān)閉
state.SocketTask.onClose(()=>{
state.IsOpen = false;
state.SocketTask = false;
//清除定時器
clearTimeout(state.interval);
state.interval = null
});
// 監(jiān)聽錯誤
state.SocketTask.onError((e)=>{
state.IsOpen = false;
state.SocketTask = false;
});
} else {
console.log('網(wǎng)絡(luò)已斷開');
state.netWork = false;
// 網(wǎng)絡(luò)斷開后顯示model
uni.showModal({
title: '網(wǎng)絡(luò)錯誤',
content: '請重新打開網(wǎng)絡(luò)',
showCancel: false,
success: function(res) {
if (res.confirm) {
console.log('用戶點(diǎn)擊確定')
}
}
})
}
}
})
},
reConnect({ commit, state }){
if (state.connectNum < 20) {
state.timer = setTimeout(() => {
this.dispatch('initWs')
}, 3000)
state.connectNum += 1;
} else if (state._connectNum < 50) {
state.timer = setTimeout(() => {
this.dispatch('initWs')
}, 10000)
state.connectNum += 1;
} else {
state.timer = setTimeout(() => {
this.dispatch('initWs')
}, 450000)
state.connectNum += 1;
}
}
}
}