vue项目使用websocket

首先来看一下轮询和websocket客户端和服务器之间关系的区别

image.png

websoket属性

属性 描述
Socket.readyState 只读属性 readyState 表示连接状态,可以是以下值:
0 - 表示连接尚未建立。
1 - 表示连接已建立,可以进行通信。
2 - 表示连接正在进行关闭。
3 - 表示连接已经关闭或者连接不能打开。
Socket.bufferedAmount 只读属性 bufferedAmount 已被 send() 放入正在队列中等待传输,但是还没有发出的 UTF-8 文本字节数。

WebSocket 事件

以下是 WebSocket 对象的相关事件。假定我们使用了以上代码创建了 Socket 对象:

事件 事件处理程序 描述
open Socket.onopen 连接建立时触发
message Socket.onmessage 客户端接收服务端数据时触发
error Socket.onerror 通信发生错误时触发
close Socket.onclose 连接关闭时触发

WebSocket 方法

以下是 WebSocket 对象的相关方法。假定我们使用了以上代码创建了 Socket 对象:

方法 描述
Socket.send() 使用连接发送数据
Socket.close() 关闭连接

项目中使用

<script>
  const heartCheck = {
  timeout: 5 * 1000,
  timer: null,
  serverTimer: null,
  reset() {
    this.timer && clearTimeout(this.timer)
    this.serverTimer && clearTimeout(this.serverTimer)
  },
  start(ws, params = {}) {
    this.reset()
    this.timer = setTimeout(() => {
      // console.log('发送心跳,后端收到后,返回一个心跳消息')
      // onmessage拿到返回的心跳就说明连接正常
      ws.send(JSON.stringify(params))
      this.serverTimer = setTimeout(() => {
        // 如果超过一定时间还没响应(响应后触发重置),说明后端断开了
        ws.close()
      }, this.timeout)
    }, this.timeout)
  }
}
export default {
  data() {
    let wsuri = 'ws://HOST:PORT/api//websocket/message'
    //判断当前是开发环境还是线上环境
    if (process.env.NODE_ENV === 'development') {
      wsuri = wsuri.replace(/HOST/, '1.1.1.1').replace(/PORT/, '8080')
    } else {
      wsuri = wsuri.replace(/HOST/, window.location.hostname).replace(/PORT/, window.location.port)
    }
    console.log('wsuri:', wsuri)
    return {
      wsuri, // ws wss
      lockReconnect: false, // 连接失败不进行重连
      maxReconnect: 5, // 最大重连次数,若连接失败
      socket: null,
      queryParams: { ip, kind: type, keyword: '' },
      cache: []
    }
  },
  mounted() {
    this.initWebSocket()
  },
  beforeRouteLeave(to, from, next) {
    if (to.name !== '当前页面') {
      heartCheck.reset()
      this.lockReconnect = true
      this.socket && this.socket.close()
      this.handleClear()
      setTimeout(() => {
        this.$destroy()
      }, 1000)
    }
    next()
  },
  methods: {
    initWebSocket() {
      try {
        if ('WebSocket' in window) {
          this.socket = new WebSocket(this.wsuri)
        } else {
          console.log('您的浏览器不支持websocket')
        }
        this.socket.onopen = this.websocketonopen
        this.socket.onmessage = this.websocketonmessage
        this.socket.onclose = this.websocketclose
        this.socket.onerror = this.websocketonerror
      } catch (e) {
        console.error('e: ', e)
      }
    },
    websocketonopen() {
      console.log('WebSocket连接成功', this.socket.readyState)
      heartCheck.start(this.socket, this.queryParams)
      this.websocketsend()
    },
    websocketsend() {
      this.socket.send(JSON.stringify(this.queryParams))
    },
    websocketonmessage(e) {
      try {
        console.log('WebSocket获取数据', e)
        const data = JSON.parse(e.data);
        [].push.apply(this.cache, [data])
        // 消息获取成功,重置心跳
        heartCheck.start(this.socket, this.queryParams)
      } catch (e) {
        console.error('e: ', e)
      }
    },
    websocketclose(e) {
      console.log('connection closed (' + e.code + ')')
      this.reconnect()
    },
    websocketonerror(e) {
      console.log('WebSocket连接发生错误', e)
      this.reconnect()
    },
    reconnect() {
      console.log('尝试重连')
      if (this.lockReconnect || this.maxReconnect <= 0) return
      setTimeout(() => {
        // this.maxReconnect-- // 不做限制 连不上一直重连
        this.initWebSocket()
      }, 5 * 1000)
    }
  }
}
</script>
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • HTML5 WebSocket WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工...
    洛的俠阅读 388评论 0 0
  • HTML5 WebSocket WebSocket是HTML5开始提供的一种在单个 TCP 连接上进行全双工通讯的...
    葛藤湾阅读 353评论 0 0
  • WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。 WebSocket...
    莫伊剑客阅读 263评论 0 0
  • Socket并非是一个协议,而是为了方便使用TCP而抽象出来的一层,是位于应用层和传输控制层之间的一组接口。换句话...
    JunChow520阅读 3,379评论 0 4
  • WebSocket协议可以实现前后端全双工通信,从而取代浪费资源的长轮询。在此协议的基础上,可以实现前后端数据、多...
    心谭阅读 970评论 0 1