美文网首页
uniapp基于vuex的websocket链接库

uniapp基于vuex的websocket链接库

作者: 万丈光芒照窝窝 | 来源:发表于2019-12-03 21:11 被阅读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;
                }
            }
        }
    }
    
    

    相关文章

      网友评论

          本文标题:uniapp基于vuex的websocket链接库

          本文链接:https://www.haomeiwen.com/subject/hophgctx.html