WebSocket(心跳机制)

90 阅读1分钟
WebSocket 是什么?

WebSocket 是基于 TCP 的一种新的应用层网络协议。它实现了浏览器与服务器全双工通信,即允许服务器主动发送信息给客户端。因此,在 WebSocket 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输,客户端和服务器之间的数据交换变得更加简单。

WebSocket 的特点
  • 建立在 TCP 协议之上;
  • 与 HTTP 协议有着良好的兼容性:默认端口也是 80(ws) 和 443(wss,运行在 TLS 之上),并且握手阶段采用 HTTP 协议;
  • 较少的控制开销:连接创建后,ws 客户端、服务端进行数据交换时,协议控制的数据包头部较小,而 HTTP 协议每次通信都需要携带完整的头部;
  • 可以发送文本,也可以发送二进制数据;
  • 没有同源限制,客户端可以与任意服务器通信;
  • 协议标识符是 ws(如果加密,则为 wss),服务器网址就是 URL;
  • 支持扩展:ws 协议定义了扩展,用户可以扩展协议,或者实现自定义的子协议(比如支持自定义压缩算法等);
WebSocket 使用(心跳机制)
<script>
export default {
  data() {
    return {  
      socket: null,
      aliveTime: new Date().getTime(),
      checkTimer: null
    }
  },
  
  computed: {
    token() {
      return this.$store.getters.token
    }
  },
  
  beforeDestroy() {
    clearInterval(this.checkTimer)
    this.socket && this.socket.close()
  },
  
  mounted() {
   if (this.socket && this.socket.readyState === 1) {
    clearInterval(this.checkTimer)
    this.socket.close()
   }
   
   if (this.socket && this.socket.readyState === 3) {
      this.initWebSocket()
   }
   
   this.getData()
  },
  
  methods: {
    getData() {
      // ......
      this.initWebSocket()
    },
    
    initWebSocket() {
      if (typeof WebSocket === 'undefined') {
        this.$message({ message: '您的浏览器不支持WebSocket' })
        return false
      }
      
      this.checkTimer && clearInterval(this.checkTimer)
      this.socket && this.socket.close()
      this.aliveTime = new Date().getTime()
      const token = this.token.split('Bearer ')[1]
      
      const wsurl = `wss://${process.env.VUE_APP_DOMAIN}/ws?token=${token}`
      this.socket = new WebSocket(wsurl)
      this.socket.onmessage = this.websocketonmessage
      this.socket.onerror = this.websocketonerror
      
      this.checkTimer = setInterval(this.checkWebsocketAlive, 5 * 1000)
    },
    
    websocketonmessage(e) {
      const response = JSON.parse(e.data)
      if (response.message === 'success') {
        const data = response.data
        // 处理 data
      }
      // 这里的场景是服务端主动推数据,接收到消息说明连接正常
      if (response.message === 'connection alive') {
        this.aliveTime = new Date().getTime()
      }
    },
    
    websocketonerror() {
      clearInterval(this.checkTimer)
      this.socket.close()
    },
    checkWebsocketAlive() {
      const now = new Date().getTime()
      if (now - this.aliveTime > 60 * 1000) {
        this.aliveTime = now
        this.initWebSocket()
      }
    },
  }
}
</script>