uniapp基于vuex的websocket链接库

2019-12-03  本文已影响0人  万丈光芒照窝窝

看了市场上已有的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;
            }
        }
    }
}

上一篇下一篇

猜你喜欢

热点阅读