封装小程序的websocket

更新日期: 2019-08-01阅读: 3.6k标签: socket

这两天的工作中,我重构了一个项目里的客服聊天功能,是小程序的,用了小程序提供的websocket有关的接口,我感觉很简单,和web端的接口大体一致,不过我喜欢封装后去使用,封装成一个类,创建一个类的实例,通过这个实例上的方法去调用方法,去监听返回的消息,同时发送消息,我觉得这样会比较方便。

/**
 * 返回一个布尔值判断传入的url是否为WSS开头的链接
 * @param {String} url 需要判断的URL
 */
function isAbsoluteWss(url) {
  return /^(wss:\/\/).*/.test(url)
}

export default class Socket {
  /** 链接的URL */
  url = ''
  /** 是否链接成功的状态 */
  socketOpenStatus = false
  /** 实例 */
  websocket = null
  /** 消息队列 */
  socketMsgQueue = []
  /** 消息监听的函数 */
  fn = null

  /**
   *
   * @param {String} url websocket的链接地址
   * @param {Function} fn 消息监听事件
   */
  constructor(url, fn) {
    if (!url)
      throw new Error('websocket的链接URL不能为空')

    if (!isAbsoluteWss(url))
      throw new Error(`websocket的链接${url}必须是以 wss:// 开头`)

    this.url = url
    this.fn = fn
  }

  /** 链接websocket */
  connect() {
    this.websocket = wx.connectSocket({
      url: this.url
    })

    // 监听websocket链接打开
    this.websocket.onOpen((data) => {
      this.socketOpenStatus = true
      // 初始化监听事件
      this.initHandleMonitor()
      if (this.fn) {
        this.fn({
          type: 'open',
          data
        })
      }

      // 如果消息队列里有消息
      if (this.socketMsgQueue.length) {
        this.socketMsgQueue.forEach(item => item())
      }

      this.socketMsgQueue = []
    })
  }

  /** 发送消息 */
  send(data) {
    if (data !== null && typeof data === 'object') {
      data = JSON.stringify(data)
    }

    // 判断当前的链接是否链接成功
    if (this.socketOpenStatus) {
      this.websocket.send({
        data
      })
    } else {
      this.socketMsgQueue.push(() => {
        this.websocket.send({
          data
        })
      })
    }
  }

  /** 监听消息的绑定 */
  initHandleMonitor() {

    /** 消息的回调 */
    this.websocket.onMessage(res => {
      const data = JSON.parse(res.data)
      if (this.fn) {
        this.fn({
          type: 'message',
          data
        })
      }
    })

    /** 报错的回调 */
    this.websocket.onError(res => {
      this.socketOpenStatus = false

      if (this.fn) {
        this.fn({
          type: 'error',
          data: res.errMsg
        })
      }
    })

    /** 关闭的回调 */
    this.websocket.onClose(data => {
      this.socketOpenStatus = false

      if (this.fn) {
        this.fn({
          type: 'close',
          data
        })
      }
    })
  }

  /** 关闭websocket链接 */
  close(code, reason) {
    if (this.socketOpenStatus) {
      this.socketOpenStatus = false
      this.websocket.close({
        code,
        reason
      })
    }
  }

  /** 返回是否链接成功 */
  isOpen() {
    return this.socketOpenStatus
  }
}
上面是我封装的代码,使用了es6的类,创建一个类,在创建的同时,传入websocket的链接地址,通过第二个参数中的回调函数实现消息的返回监听。第一个方法是判断传入的连接链接是否有效,只是一个简单的判断,只判断传入的参数是否符合wss://开头,后续需要修改完善。
我在类中写了initHandleMonitor这个方法,是因为事件的绑定函数,需要在websocket链接成功后,并返回了这个实例,才能在实例上绑定,所以我选择在websocket链接成功后绑定,并执行websocket未链接成功前,已经发送的命令。返回的消息,返回一个对象,对象中有两个属性,一个为type是消息的类型,一个是data是websocket中发的消息。
send方法中,通过判断当前传入的消息体的数据类型,如果是非字符串,则使用JSON.stringify()来JSON格式化消息体,因为小程序的data只能发送字符串string和ArrayBuffer。send在每一次发送消息前会去判断websocket是否已经构建成功。


链接: https://fly63.com/article/detial/5074

web Socket和Socket.IO框架

HTTP无法轻松实现实时应用:HTTP协议是无状态的,服务器只会响应来自客户端的请求,但是它与客户端之间不具备持续连接。我们可以非常轻松的捕获浏览器上发生的事件(比如用户点击了盒子)

Nginx 转发 socket 端口配置

Nginx 转发 socket 端口常见场景:在线学习应用,在常规功能之外,增加一个聊天室功能,后端选择 swoole 提供服务提供者,同时不想前端直接 ip:port 方式链接到服务,需要使用 Nginx 进行转发。

websocket.io

服务器端:使用express服务;简单的使用websocket.io;使用命名空间 实例中两个命名空间info job;客户端 vue为例引入socket.io-client

Socket通信原理.一文了解Socket

Socket 的中文翻译过来就是“套接字”。套接字是什么,我们先来看看它的英文含义:插座。Socket 就像一个电话插座,负责连通两端的电话,进行点对点通信,让电话可以进行通信,端口就像插座上的孔,端口不能同时被其他进程占用。而我们建立连接就像把插头插在这个插座上

Vue.js 如何使用 Socket.IO

Socket.IO是一个WebSocket库,可以在浏览器和服务器之间实现实时,双向和基于事件的通信。它包括:Node.js服务器库、浏览器的Javascript客户端库。它会自动根据浏览器从WebSocket、AJAX长轮询、

轮询、长轮询、长连接、socket连接、WebSocket

轮询:客户端定时向服务器发送Ajax请求,服务器接到请求后马上返回响应信息并关闭连接;长轮询:客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接

使用Promise封装Websocket

await 后面若是跟的Promise,则接受Promise resolve的值。Promise reject的值需要try...catch住,或者await 后面的表达式跟着.catch()

socket.io的接入使用

传统的客户端和服务器通信协议是HTTP:客户端发起请求,服务端进行响应,服务端从不主动勾搭客户端。这种模式有个明显软肋,就是同步状态。而实际应用中有大量需要客户端和服务器实时同步状态的场景

如何在 React 中正确的使用 socket.io 客户端?

最近在一个 React 项目中,使用到了 socket.io 处理即时消息,这里面有几点容易被忽视的问题,例如:在 React 单页面应用中如何防止出现多个 socket 实例、在任意的的组件内如何方便的取到 socket 实例

Web 全栈推拉能手 Socket.IO 库

Socket.IO 不仅支持 WebSocket,还支持许多种轮询机制以及其他实时通信方式,并封装了通用的接口。这些方式包含 Adobe Flash Socket、Ajax 长轮询、Ajax multipart streaming 、持久 Iframe、JSONP 轮询等

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!