收藏
回答

官方能否给一个SocketTask的具体事例啊?

wx.connectSocket是异步的,那么如何获取SocketTask?以及如何用SocketTask监听?

现在文档给的都是分散的,希望官方一共一个完整的例子。

现在弄得一头雾水。

回答关注问题邀请回答
收藏

3 个回答

  • 尼克
    尼克
    2022-05-12

    1、socket.js 文件

    import config from '@config'

    const host = config.wsHOST

    export default class WebSocket {

        constructor({ heartBeat, roomId, onMessage }) {

            // 是否已连接

            this.connected = false

            // 当前网络状态

            this.netWorkState = true

            // 心跳检测频率

            this.timeout = 15000

            // 计时器ID

            this.timer = null

            // 当前重连次数

            this.connectNum = 0

            // 心跳检测和断线重连开关

            this.heartBeat = heartBeat

            // 房间id

            this.roomId = roomId

            // 回调监听

            this.message = onMessage

            // socketTask

            this.socketTask = null

            // 初始化

            this.initWebSocket()

        }

        /**

         * 建立websocket连接

         * @param {*} options 

         */

        initWebSocket(options) {

            const that = this

            if (this.connected) {

                console.log("socket已连接")

            } else {

                // 检查网络

                wx.getNetworkType({

                    success(net) {

                        if (net.networkType != 'none') {

                            const appId = that.appId()

                            that.socketTask = wx.connectSocket({

                                url: `${host}${that.roomId}/${appId}`,

                                success(res) {

                                    console.log('socket连接成功', res)

                                    // 已连接

                                    that.connected = true

                                },

                                fail(err) {

                                    console.log('socket连接失败', err)

                                }

                            })

                            // 监听 WebSocket 连接打开事件

                            that.onSocketOpened()

                            // 监听 WebSocket 连接关闭事件

                            that.onSocketClosed()

                            // 监听websocket 错误

                            that.onSocketError()

                            // 存在发生数据则需要发送数据

                            if (options) {

                                that.sendWebSocketMsg(options)

                            }

                        } else {

                            that.netWorkState = false

                        }

                    }

                })

            }

        }

     


    2022-05-12
    有用 1
    回复 2
    • 尼克
      尼克
      2022-05-12
      /**


           * WebSocket 错误事件的回调函数


           */


          onSocketError() {


              const that = this


              that.socketTask.onError((errMsg) => {


                  console.log(errMsg)


              })


          }


          /**


           * 监听 WebSocket 连接打开事件


           */


          onSocketOpened() {


              const that = this


              that.socketTask.onOpen(


                  (res) => {


                      console.log('socketTask.onOpen',res)


                      // 检查心跳


                      if (that.heartBeat) {


                          that.resetHeartBeat()


                          that.startHeartBeat()


                      }


                      that.sendTestMessage()


                      that.onReceivedMsg()


                      // 网络状态


                      that.netWorkState = true


                  }


              )


          }


          /**


           * 心跳检查重置


           */


          resetHeartBeat() {


              this.timer && clearTimeout(this.timer)


          }


          /**


           * 心跳检查开始


           */


          startHeartBeat() {


              const that = this


              that.timer = setInterval(() => {


                  that.sendTestMessage()


              }, that.timeout)


          }    


          /**


           * 发送hearBeat测试信息


           */


          sendTestMessage() {


              const that = this


              that.socketTask.send({


                  // 心跳发送的信息应由前后端商量后决定


                  data: 'HeartBeat',


                  success(res) {


                      console.log('发送测试信息成功', res)


                  },


                  fail(err) {


                      console.log('发送测试信息失败', err)


                      that.resetHeartBeat()


                  }


              })


          }
      2022-05-12
      1
      回复
    • 尼克
      尼克
      2022-05-12
      /**


           * 监听websocket连接关闭


           */


          onSocketClosed() {


              const that = this


              that.socketTask.onClose((code, reason) => {


                  console.log(`连接已关闭,信息:${code}-${reason}`)


                  // 停止心跳连接


                  if (this.heartBeat) {


                      this.resetHeartBeat()


                  }


                  // 更新已连接状态


                  this.connected = false


              })


          }


          /**


           * 重连方法,会根据时间频率越来越慢


           * @param {*} options 


           */


          reConnect(options) {


              if (this.connectNum < 20) {


                  setTimeout(() => {


                      this.initWebSocket(options)


                  }, 3000)


                  this.connectNum += 1


              } else if (this.connectNum < 50) {


                  setTimeout(() => {


                      this.initWebSocket(options)


                  }, 10000)


                  this.connectNum += 1


              } else {


                  setTimeout(() => {


                      this.initWebSocket(options)


                  }, 450000)


                  this.connectNum += 1


              }


          }


          /**


           * 获取随机数


           * @returns 


           */


          appId() {


              return Math.floor(Math.random() * 4294967294 + 1);


          }


          /**


           * 接收服务器返回的消息


           */


          onReceivedMsg() {


              const that = this


              console.log('socketTask.onMessage')


              that.socketTask.onMessage((data) => {


                  this.message && this.message(data)


              })


          }


          /**


           * 发送websocket消息


           * @param {*} options 


           */


          sendWebSocketMsg(options) {


              const that = this


              const data = { ...options.data, roomId: that.roomId, topic: `topic_${that.roomId}` }


              that.socketTask.send({


                  data: JSON.stringify(data),


                  success() {


                      console.log('发送消息成功', data)


                  },


                  fail(err) {


                      console.log('发送消息失败', err)


                      that.reConnect(options)


                  }


              })


          }


          /**


           * 关闭websocket连接


           */


          closeWebSocket() {


              const that = this


              that.socketTask.close(


                  {


                      success(res) {


                          console.log('关闭socket成功', res)


                          that.heartBeat = false


                      },


                      fail(err) {


                          console.log('关闭socket失败', err)


                      }


                  }


              )


          }


      }


      2、勉强能使用


      ———————————————


      import WebSocket from '@utils/WebSocket'


      const roomId = 'XXXXX'


      const socket = new WebSocket({


            heartBeat:true,


            roomId,


            onMessage: this._onMessage


        })


      _onMessage = (data) => {


          const that = this;


          if (data && data.data != 'health') {


            data = JSON.parse(data?.data)


          }


          console.log('socket回调结果处理',data)


      }
      2022-05-12
      回复
  • 会飞的蜗牛
    会飞的蜗牛
    2022-08-22
      webSocketInit () {
        const vm = this
        let token = ''
        let socketUrl = 'wss://websocket.test'
        // 建立 WebSocket 连接
        vm.socket = wx.connectSocket({
          url: socketUrl,
          header: {
            'content-type': 'application/json',
            'authorization': 'Bearer' + token,
            'x-wxapp-sockettype': 'ordertips'
          },
          success (res) {
            console.log('WebSocket 连接成功: ', res)
          },
          fail (err) {
            console.log('WebSocket 连接失败: ', err)
          }
        })
        // onOpen
        vm.socket.onOpen((ret) => {
          console.log('打开 WebSocket 连接')
        })
        // onMessage
        vm.socket.onMessage((ret) => {
          if (ret.data == 'pong') {
            return;
          }
          let data = JSON.parse(ret.data)
          wx.showToast({
            title: data.message,
            icon: 'none',
            duration: 3000
          })
        })
        // onError
        vm.socket.onError((err) => {
          console.log('WebSocket 连接失败:', err)
        })
        // onClose
        vm.socket.onClose((ret) => {
          console.log('断开 WebSocket 连接', ret)
        })
      },
      // send message
      send (msg) {
        const vm  = this
        vm.socket.send({
          data: msg,
          success (res) {
            console.log('WebSocket 消息发送成功', res)
          },
          fail (err) {
            console.log('WebSocket 消息发送失败', err)
          }
        })
      },
      // 心跳,由客户端发起
      ping () {
        const vm = this
        let times = 0
        // 每 10 秒钟由客户端发送一次心跳
        this.interval = setInterval(function () {
          if (vm.socket.readyState == 1) {
            vm.send('ping')
          } else if (vm.socket.readyState == 3) {
            times += 1
            // 超时重连,最多尝试 10 次
            if (times >= 10) {
              wx.showToast({
                title: 'WebSocket 连接已断开~',
                icon: 'none',
                duration: 3000
              })
              clearInterval(vm.interval)
            }
            vm.reconnect()
          }
        }, 10000)
      },
      // WebSocket 断线重连
      reconnect () {
        const vm = this
        vm.webSocketInit()
      },
    
    2022-08-22
    有用
    回复 2
    • 5132
      5132
      2023-02-12
      我参照你的这段代码,我的出错显示:Error: MiniProgramError
      {"errMsg":"closeSocket:fail WebSocket is not connected"}
      2023-02-12
      回复
    • 万能的布洛芬
      万能的布洛芬
      2023-02-24回复5132
      检查你连接的服务器是否已经运行, 端口是否已经开放, 还有就是不要使用127.0.0.1为地址, 因为如果你用本机作为服务器, 手机测试的话是连不到本机的
      2023-02-24
      回复
  • 沫秋
    沫秋
    2022-04-05

    就是就是。 TCPSocket 还好多bug

    2022-04-05
    有用
    回复
登录 后发表内容