看了市场上已有的ws 库都不是很想要的,因为都没有自动重连功能,所以自己开发了一个,不定期维护代码。
使用方法在store里面建立以一个新的模块引入
包含了断线重连,心跳检测等
import config from '@/config/config.js'
export default {
state:{
//链接是否打开了
IsOpen:false,
// SocketTask
SocketTask:false,
//绑定的fd
bindFd:null,
// 当前聊天对象(进入聊天页面获取)
Network:true,
//断线重连定时器
timer:null,
//心跳间隔
timeout:10000,
//心跳事件
interval:null,
// 当前重连次数
connectNum : 0,
//当前聊天场景
CurrentToUser:{
id:0, // 用户ID,或者群聊ID
name:"",//type=chat,就是昵称,group,就是群聊名称
avatar:"",
type:"chat",//group 群聊,
},
noreadnum:0,//当前总未读消息数量,最大99
},
mutations:{
// 关闭连接
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; // 防止重复连接
//检查网络是否可用
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;
// 监听开启
state.SocketTask.onOpen(()=>{
console.log('链接成功')
// 将连接状态设为已连接
state.IsOpen = true;
//开启心跳
state.interval=setInterval(() => {
//发送心跳
uni.sendSocketMessage({
data : 'PING',
fail:function(e){
console.log('心跳发送失败了 ...执行重连');
uni.showToast({
title: '正在尝试重新链接第'+state.connectNum+'次',
icon:"none",
});
state.IsOpen = false;
//执行重连
//_this.dispatch('reConnect')
_this.dispatch('reConnect');
},
});
}, state.timeout);
});
// 监听信息
state.SocketTask.onMessage((e)=>{
console.log(e.data);
if(e.data !=='PONG'){
// 字符串转json
let res = JSON.parse(e.data);
console.log(res);
//根据消息类型分发事件
switch(res.msg_type){
case 'close':
if (state.IsOpen){
state.SocketTask.close();
}
break;
case 'bindResult':
state.bindFd = res.fd;
break;
case 'chat':
//聊天消息
//根据消息内容处理业务
// 总未读数+1
if (state.CurrentToUser.id !== res.from_id) {
if(state.noreadnum < 99){
noreadnum +=1;
}
}
break;
}
}
})
// 监听关闭
state.SocketTask.onClose(()=>{
state.IsOpen = false;
state.SocketTask = false;
//清除定时器
clearTimeout(state.interval);
state.interval = null
});
// 监听错误
state.SocketTask.onError((e)=>{
state.IsOpen = false;
state.SocketTask = false;
});
} else {
console.log('网络已断开');
state.netWork = false;
// 网络断开后显示model
uni.showModal({
title: '网络错误',
content: '请重新打开网络',
showCancel: false,
success: function(res) {
if (res.confirm) {
console.log('用户点击确定')
}
}
})
}
}
})
},
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;
}
}
}
}
网友评论