uniapp集成websocket不断线的处理-打牌记账

背景

近期在开发打牌记账微信小程序时,我们将房间这个业务场景做成了类似聊天室功能。

对房间内发生的动作,都能实时对其他人可见。 如:转账,离开,加入,结算等动作

其他人员都能实时接收到推送消息, 这个时候就需要websocket发挥作用。

uniapp集成websocket 会出现断线的情况。

导致用户体验差,基经过一番排查,解决了异常。 感兴趣扫描下方小程序码在线体验.

a1.png

解决方法

请先阅读之前文章uniapp集成websocket的前后端代码了解集成步骤。

一般情况下,小程序是由多个页面构成的,那么这里就有两种情况:

你的长连接返回的数据只是某一个页面需要用到,其他页面都没有用到;

你的长连接返回的数据不止一个页面用到,而是多个页面,这种情况当然也可以包括第一种情况。

  • 单页面监听代码实现
var socket = null;

export default{

...

onShow(){

socket = uni.connectSocket({

     url: 'wss://www.example.com/socket', //仅为示例,并非真实接口地址。

     complete: ()=> {}

});

socket.onOpen(()=>{console.log('conn')});

socket.onMessage(res=>{...to do});//获取服务器传来的数据,做相应处理

socket.onClose(()=>{console.log('close')});

socket.onError((err)=>{console.log(err)})

},

onHide(){

socket.close();

},...

}

这样的效果是每次打开该页面,都会创建一个长连接,关闭该页面,都会关闭该连接。

如果你希望始终使用一个长连接,那么你可以把onShow()中的部分移到onLoad()中,但是你需要把onHide()中的关闭连接事件删除。
这样从第一次打开该页面开始,长连接就创建,此后始终保持,

但是如果小程序进入后台,这个长连接就会自动断开,重新打开小程序,onLoad()事件没有触发创建连接,所以你需要在onShow()中做一个心跳重连监测

以上是网上提供的思路, 下面是自己实践之后的代码

uniapp代码实现
onLoad(e) {
        console.log("on load");
        this.loadRoom(e);
},
onShow() {
        console.log("onShow");
        if(this.hasLogin && this.roomId != null){
                this.createWebsocket()
                console.log("---connect done--");
        }

},
destroyed() {
        if(this.socketTask != null){
                this.socketTask.closeConnect();
        }
        if(this.joinSocket != null){
                this.joinSocket.closeConnect();
        }
        if(this.offlineSocket != null){
                this.offlineSocket.closeConnect();
        }
        if(this.checkoutSocket != null){
                this.checkoutSocket.closeConnect();
        }
},
methods: {
    async loadRoom(e){
            await this.refreshMyToken();
            //根据机型调整房间人员框的高度
            this.getPersonBoxMaxHeight();
             //获取跳转携带的roomId:好友分享和微信扫一扫
             this.roomId = e.roomId;
             if(this.roomId === null || this.roomId === undefined || this.roomId === 'null'){
                     const scene = decodeURIComponent(e.scene)
                     this.roomId = scene.split("=")[1];
             }
             //进行登陆判断
             if(this.hasLogin === false){
                     this.$local.set("share_redirect_path", "/pages/index/room?roomId="+this.roomId);
                     uni.redirectTo({
                            url:'/pages/login/index'
                     })
                     return;
             }
             //加入房间
             this.joinRoom(this.roomId)

             //建立连接
             this.createWebsocket()

    },
    //建立ws链接
		createWebsocket(){
			if(this.socketTask == null){
				this.socketTask = new wsRequest(this.serviceUrl + "/jeecg-activiti-gateway/ws/push/"+this.roomId + "/"+ this.userInfo.id, 3000);
				this.watchSocket();
			}
			if(this.offlineSocket == null){
				this.offlineSocket = new  wsRequest(this.serviceUrl + "/jeecg-activiti-gateway/ws/offline/"+this.roomId + "/"+ this.userInfo.id, 3000);
				this.watchOfflineSocket();
			}
			if(this.joinSocket == null){
				this.joinSocket = new wsRequest(this.serviceUrl + "/jeecg-activiti-gateway/ws/join/"+this.roomId + "/"+ this.userInfo.id, 3000);
				this.watchJoinSocket();
			}
			
			if(this.checkoutSocket == null){
				this.checkoutSocket = new wsRequest(this.serviceUrl + "/jeecg-activiti-gateway/ws/checkout/"+this.roomId + "/"+ this.userInfo.id, 3000);
				this.watchCheckoutSocket();
			}
			
		},
  }

实现思路,在onLoad函数,我们就创建了websocket,并且实现了心跳机制检测。

此时,如果小程序退出,将执行destroyed函数将socket关闭

如果重新进入该页面,则会执行onShow函数,重新建立连接。 如此实现了不断连的效果。

参考

uniapp之微信小程序开发WebSocket

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值