微信小程序使用 Websocket

基本思路是:

  1. 全局维护一个SocketTask对象,用来表示websocket连接,判断是否断线,作为重连的依据。
  2. 同时定义一个全局callback回调函数,每个页面初始化的时候更新这个回调函数,那么在每个页面中收到返回消息就会执行当前页面逻辑。
  3. 维护一个消息队列,所有消息请求会首先判断连接是否可用,如果可用直接发消息,否则将消息push到这个队列中。
  4. 在app.js的onShow()函数中判断连接是否连上,如果没有连上就会触发websocket连接
  5. SocketTask对象的onOpen()负责从消息队列中取出请求消息,并发送这个请求消息
  6. SocketTask对象的onMessage()负责接收返回消息,并调用每个页面自己定义的回调函数
  7. SocketTask对象的onClose()监听函数中,触发websocket连接

下面是app.js代码:

let socketMsgQueue = []
let isLoading = false

App({
  globalData: {
    userInfo: null,
    localSocket: {},
    callback: function () {}
  },
  onLaunch: function (options) {
    // 展示本地存储能力
    var logs = wx.getStorageSync('logs') || []
    logs.unshift(Date.now())
    wx.setStorageSync('logs', logs)
    const updateManager = wx.getUpdateManager()
    updateManager.onUpdateReady(function () {
      updateManager.applyUpdate()
    })
    let that = this
    
    // 登录
    wx.login({
      success: res => {
        // 发送 res.code 到后台换取 openId, sessionKey, unionId
      }
    })
    // 获取用户信息
    wx.getSetting({
      success: res => {
        if (res.authSetting['scope.userInfo']) {
          // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
          wx.getUserInfo({
            success: res => {
              // 可以将 res 发送给后台解码出 unionId
              this.globalData.userInfo = res.userInfo
              // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
              // 所以此处加入回调以防止这种情况
              if (this.userInfoReadyCallback) {
                this.userInfoReadyCallback(res)
              }
            }
          })
        }
      }
    })
  },
  showLoad() {
    if(!isLoading) {
      wx.showLoading({
        title: '请稍后...',
      })
      isLoading = true
    }
  },
  hideLoad() {
    wx.hideLoading()
    isLoading = false
  },
  initSocket() {
    let that = this
    that.globalData.localSocket = wx.connectSocket({
      // url: 'wss://test.enzhico.net/app'
      url: 'wss://mapp.enzhico.net/app'
    })
    that.showLoad()
    that.globalData.localSocket.onOpen(function (res) {
      console.log('WebSocket连接已打开!readyState=' + that.globalData.localSocket.readyState)
      that.hideLoad()
      while (socketMsgQueue.length > 0) {
        var msg = socketMsgQueue.shift();
        that.sendSocketMessage(msg);
      }
    })
    that.globalData.localSocket.onMessage(function(res) {
      that.hideLoad()
      that.globalData.callback(res)
    })
    that.globalData.localSocket.onError(function(res) {
      console.log('readyState=' + that.globalData.localSocket.readyState)
    })
    that.globalData.localSocket.onClose(function (res) {
      console.log('WebSocket连接已关闭!readyState=' + that.globalData.localSocket.readyState)
      that.initSocket()
    })
  },
  //统一发送消息
  sendSocketMessage: function (msg) {
    if (this.globalData.localSocket.readyState === 1) {
      this.showLoad()
      this.globalData.localSocket.send({
        data: JSON.stringify(msg)
      })
    } else {
      socketMsgQueue.push(msg)
    }
  },
  onShow: function(options) {
    if (this.globalData.localSocket.readyState !== 0 && this.globalData.localSocket.readyState !== 1) {
      console.log('开始尝试连接WebSocket!readyState=' + this.globalData.localSocket.readyState)
      this.initSocket()
    }
  }
})

下面是某个页面的onshow()函数:

onShow: function () {
  var that = this
  app.globalData.callback = function (res) {
    let resData = JSON.parse(res.data)
    let data = resData.result
    if (resData.method == 'list') {
      that.setData({
        total: parseInt(data.allAmount),
        amount: data.orderNum,
        jdcAmount: parseInt(data.jdcAmount),
        jszAmount: parseInt(data.jszAmount),
        list: data.list || []
      })
      if(data.list == 0) {
        that.setData({
          isEmpty: true
        })
      }
      that.getNumber(resData.result.allAmount)
      that.setAmount()
    } else if (resData.method == 'notify') {
      // 服务器推送消息,省略具体逻辑
    }
  }
  setTimeout(function () {
    app.sendSocketMessage({
      method: 'list'
    })
  }, 300)
},

https://www.xncoding.com/2017/12/15/weixin/ma-websocket.html

猜你喜欢

转载自blog.csdn.net/henryhu712/article/details/85195952