ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

微信小程序创建WebSocket链接

2022-06-01 19:34:35  阅读:124  来源: 互联网

标签:WebSocket log url 微信 clearInterval socketTask let console 链接


 

微信小程序创建WebSocket链接使用到了uni.connectSocket(OBJECT)

这里主要讲一下单页面监听(局部监听)和多页面监听(全局监听)

 

 

 在各个小程序平台运行时,网络相关的 API 在使用前需要在【微信公众平台】配置域名白名单。注意:小程序中必须是 wss:// 协议

  • 微信小程序平台1.7.0 及以上版本,最多可以同时存在5个WebSocket 连接。老版本只支持一个socket连接

 

 

先来了解一下小程序的生命周期(只显示了主要的)

 

 

 一、局部监听

在util文件夹下建立websocket.js文件,util文件也是我自己在项目根目录建立的,主要存放使用的工具。

let isSocketClose=false;    // 是否关闭socket
let reconnectCount=5;    // 重连次数
let heartbeatInterval="";   // 心跳定时器
let socketTask = null;  // websocket对象

let  againTimer = null;//断线重连定时器

let url = null;
let onReFn = null;
let onSucFn = null;
let onErrFn = null;

/**
 * sockeUrl:websocet的地址
 * onReceive:消息监听的回调
 * one rrorEvent:抛出错误的回调,且弹窗连接失败的提示框
 * one rrorSucceed:抛出成功回调,主要用于隐藏连接失败的提示框
 * */
const sokcet= (sockeUrl,onReceive,onErrorEvent,onErrorSucceed)=> {
               url = sockeUrl;
               onReFn= onReceive;
               onErrFn= one rrorEvent;
               onSucFn= one rrorSucceed;
               isSocketClose=false; 
              //判断是否有websocet对象,有的话清空
               if(socketTask){
                   socketTask.close();
                   socketTask = null;
                   clearInterval(heartbeatInterval);
               }
    
               //WebSocket的地址
                // 【非常重要】必须确保你的服务器是成功的,如果是手机测试千万别使用ws://127.0.0.1:9099【特别容易犯的错误】
                let url = sockeUrl
                // 连接
            socketTask = uni.connectSocket({
                    url: url,
                    success(data) {
                                console.log("websocket连接成功");
                                clearInterval(againTimer)//断线重连定时器
                            },
                    fail: (err) => {
                        console.log("报错",err);
                    }
                });
                // 连接打开
                socketTask.onOpen((res)=>{
                    console.log('WebSocket打开');
                    clearInterval(againTimer)//断线重连定时器
                     one rrorSucceed({isShow:false}) // 用于提示框的隐藏
                    heartbeatInterval && clearInterval(heartbeatInterval);
                    // 发送一次心跳
                    heartbeatInterval = setInterval(() => {
socket()
            }, 1000)
            })
                 // 监听连接失败
                socketTask.onError((err)=>{
                    console.log('WebSocket连接打开失败,请检查',err);
                    //停止发送心跳
                    clearInterval(heartbeatInterval)
                    //如果不是人为关闭的话,进行重连
                    if (!isSocketClose) { 
                        reconnect(url,onErrorEvent)
                    }
                })
             
                // // 监听连接关闭 -
                socketTask.onClose((e) => {
                            console.log('WebSocket连接关闭!');
                            clearInterval(heartbeatInterval)
                            if (!isSocketClose) {
                                reconnect(url,onErrorEvent)
                            }
                    })

                // 监听收到信息
                socketTask.onMessage((res) => {
                        uni.hideLoading()
                        // console.log(res,'res监听收到信息')
                        let serverData = res.data
                        //与后端规定好返回值分别代表什么,写业务逻辑
                          serverData && onReceive(serverData);
                });
                
            
}

    const reconnect = (url,onErrorEvent)=>{
                 console.log('进入断线重连',isSocketClose);
                     clearInterval(againTimer)//断线重连定时器
                     clearInterval(heartbeatInterval);
                     socketTask && socketTask.close(); // 确保已经关闭后再重新打开
                     socketTask = null;
                    one rrorEvent({isShow:true,messge:'扫描头服务正在连接...'})
                    // 连接  重新调用创建websocet方法
                againTimer    = setInterval(()=>{
                     sokcet(url,onReFn,onErrFn,onSucFn)
                     console.log('在重新连接中...');
                 },1000)
                    
                                        
        }    

  const sendMsg = (msg)=>{   //向后端发送命令
                msg = JSON.stringify(msg)
                try{
                    //通过 WebSocket 连接发送数据
                    socketTask.send({
                        data: msg
                    });
                }catch(e){
                    if(isSocketClose){
                        return
                    }else{
                        reconnect(url,onErrFn)
                    }

                }
            }
// 关闭websocket【必须在实例销毁之前关闭,否则会是underfined错误】beforeDestroy() {websocetObj.stop();}
            
const stop = ()=>{
         isSocketClose = true
        clearInterval(heartbeatInterval);
        clearInterval(againTimer)//断线重连定时器
        socketTask.close(); // 确保已经关闭后再重新打开
        socketTask = null;
        console.log('关闭Socket')
}

 

 
 
 export const websocetObj = {
     sokcet,
     stop,
    sendMsg
 };
 

在需要的页面引入

import { websocetObj } from '@/utils/websocket.js';

在方法中写入连接的方法以及回调函数

 // 在onload的时候调用,创建webscoet连接对象,参数分别为:url、获取后端返回数据、监听websocket的链接失败返回的报错、监听链接状态,返回布尔值
            conSocket(){
                // websocetObj.sokcet(this.url,this.getWebsocetData,this.getWebsocetError,this.onErrorSucceed)
            },
            //websocet函数回调:返回监听的数据
            getWebsocetData(val){
            // val = String.fromCharCode.apply(null, new Uint8Array(val)).trim()  如果后端返回数据格式是其他的,可能需要转换一下
                let info = JSON.parse(val)
                info.detailShow = true
                this.renwuList.push(info)
                // this.scanCode = val;
            },
            //websocet函数抛错: 返回错误信息 用于用户提示
            getWebsocetError(err){
                // this.socketShow = err.isShow;
             //    this.webtext = err.messge;
                console.log('websocet函数抛错',this.socketShow);
            },
            //websocet函数成功进入: 监听连接状态,在失败的时候弹窗提示,具体需求看自身情况
            one rrorSucceed(val){
                // this.socketShow = val.isShow;
                console.log('websocet函数成功进入',val);
            }

离开这个页面可以在进入的另一个页面添加关闭socekt事件

  首先还是先引入websocket.js文件

    import { websocetObj } from '@/utils/websocket.js';

  然后在onShow()中添加

    websocetObj.stop()

但是点击navBar上面的返回,不能触发小程序的生命函数

 

 

 可以在App.vue中做一个全局标记,例如在onLaunch()中添加

uni.setStorageSync('openSocket',true)

表明webSocket打开了,在需要关闭socket的页面中,通过在onShow()中获取uni.getStorageSync('openSocket')判断socekt的状态,若为true,关闭socekt,将openSocket置位false。进入获取socket连接的页面再将openSocket置位ture.

二、全局监听

建立globalSocket.js

let isSocketClose=false;    // 是否关闭socket
let heartbeatInterval="";   // 心跳定时器
let socketTask = null;  // websocket对象

let  againTimer = null;//断线重连定时器
let that = this
let url = null;
import store from '../store' 

    const reconnect = (url)=>{
                console.log('进入断线重连',isSocketClose);
                clearInterval(againTimer)//断线重连定时器
                clearInterval(heartbeatInterval);
                socketTask && socketTask.close(); // 确保已经关闭后再重新打开
                socketTask = null;
                // 连接  重新调用创建websocet方法
                againTimer    = setInterval(()=>{
                     console.log('在重新连接中...');
                     openWs(url)
                 },1000)
                    
                                        
        }    

//监测链接,若是断开就重连
function checkWs(){
    //心跳重连
    if([2,3].includes(socketTask.readyState)){//closing 或 closed
        console.log('心跳重连...')
        socket.close();
        socket = null;
        openWs(url);
    }
}
            
const stop = ()=>{
    isSocketClose = true
    clearInterval(heartbeatInterval);
    clearInterval(againTimer)//断线重连定时器
    socketTask.close(); // 确保已经关闭后再重新打开
    socketTask = null;
    console.log('关闭Socket')
}

//socket建立和监听
const openWs= (conUrl)=> {
    //建立socketSocket和监听ws代码
    url = conUrl
    socketTask = uni.connectSocket({
            url: conUrl,
            success(data) {
                console.log("websocket连接成功");
                clearInterval(againTimer)//断线重连定时器
            },
            fail: (err) => {
                console.log("连接报错",err);
            }
        });
    
    // 连接打开
    socketTask.onOpen((res)=>{
        // console.log('WebSocket打开');
        clearInterval(againTimer)//断线重连定时器
        heartbeatInterval && clearInterval(heartbeatInterval);
        // 60秒发送一次心跳
        heartbeatInterval = setInterval(() => {
            checkWs()
        }, 10000*6)
    })
     // 监听连接失败
    socketTask.onError((err)=>{
        // console.log('WebSocket连接打开失败,请检查',err);
        //停止发送心跳
        clearInterval(heartbeatInterval)
        //如果不是人为关闭的话,进行重连
        if (!isSocketClose) { 
            reconnect(url)
        }
    })
                     
    // 监听连接关闭
    socketTask.onClose((e) => {
                // console.log('WebSocket连接关闭!');
                // clearInterval(heartbeatInterval)
                if (!isSocketClose) {
                    reconnect(url)
                }
        })
        
    // 监听收到信息
    socketTask.onMessage((res) => {
            let serverData = res.data
            //与后端规定好返回值分别代表什么,写业务逻辑
            // serverData && onReceive(serverData);
            uni.setStorageSync('dataInfo',serverData)
            store.dispatch('app/set_renWuSocektData_fun', serverData)
    });
}

 
 
 export const websocetObj = {
     stop,
    openWs
 };
 

在App.vue组件中引入

<script>
    var launched = true;  // onLaunch全局触发一次,再次打开用Onshow触发
    import { websocetObj } from '@/utils/globalSocket.js';
    import { g_config } from '@/static/global.config.js'
    export default {
        onLaunch: function() {
            websocetObj.openWs(g_config.conUrl)
        },
        onShow: function() {
          if(launched){
                    launched = false;
                }else{
                    //建立socketSocket和监听ws代码
                    websocetObj.openWs(g_config.conUrl)
                }
     }, 
    onHide: function() {
      // console.log('App Hide')
      websocetObj.stop();
      console.log('关闭Socket') }
    }
</script>
<style> </style>
<style lang="scss"></style>

在需要获取数据的页面添加watch,和data()函数同级

watch: {
            '$store.state.app.renWuSocektData': {
                handler(newVal, oldVal) {
                    // console.log(newVal)
                    if(newVal !== null){
                        this.getWebsocetData(newVal)
                    }
                },
                // immediate: true,
                deep: true
            }
        },
$store.state.app.renWuSocektData使用到了vuex,下次再用一篇博客讲解vuex的使用。



参考代码:http://www.javashuo.com/article/p-qhmvfmbv-gk.html

 

标签:WebSocket,log,url,微信,clearInterval,socketTask,let,console,链接
来源: https://www.cnblogs.com/wq805/p/16335364.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有