websocket中Node.js中的应用

简介

WebSocket 协议在2008年诞生,2011年成为国际标准。所有浏览器都已经支持了。

它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。

其他特点包括:

(1)建立在 TCP 协议之上,服务器端的实现比较容易。

(2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。

(3)数据格式比较轻量,性能开销小,通信高效。

(4)可以发送文本,也可以发送二进制数据。

(5)没有同源限制,客户端可以与任意服务器通信。

(6)协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。

readyState

Constant Value Description
CONNECTING 0 The connection is not yet open.
OPEN 1 The connection is open and ready to communicate.
CLOSING 2 The connection is in the process of closing.
CLOSED 3 The connection is closed.
坑点: websocket.readyState ===3 这里 没有走 close 的生命周期

断线重连解决方案

  1. 在websocket/ws 这个框架中,会有open,message,close 和 error生命周期。
  2. 可以在 close 的生命周期中,执行reconnect流程参考最高赞答案.然后在error的生命周期中 打印crash日志,由于 error 必定触发close 所以只需要在 close 生命周期中进行 reconnect方法。

    ws.on("close", function close() {
     console.log("ai connect close");
     reconnect(); /// 每隔5s 重连 
    });
    ws.on("error", function error(error) {
     console.log("ai connect error", error);
     errorLogger.error("ai connect error", error); //打印crash日志
     ws.close()
    });
  3. readyState=3 不会触发close的生命周期,所以需要对其单独处理,一旦检测到 其为3,则 terminate()该websocket.当然还有一种解决方案,因为在websocket中有心跳包的存在,详见How to detect and close broken connections?,可以在接收到来自其他socketServer的'pong'的信号,则写一个定时器,如果规定时间内,没有收到来自下一个的心跳包则 terminate 该socket

    if (message === 'pong') {
         clearTimeout(aliveInterval);
         aliveInterval = setTimeout(function () {
             wsObj.wsAI.terminate()
         }, 10000 + 1000)
    }

ws/websocket 官方Tip: Use WebSocket#terminate(), which immediately destroys the connection,
instead of WebSocket#close(), which waits for the close timer.
之我的理解: terminate() 能够立马 destory 连接,如果是close()的话,意味着还需要等待 close 的任务

工程化 Tips:

  • 当我们搭建 websocketServer的时候,常常会遇到socket.readyState =0 的情况, 会报Error: WebSocket is not open: readyState 0 (CONNECTING)这个错误,所以在我们和每个socket通信的时候,可以增加前提 ws.readyState===1 才进行ws.send(),否则socket中断,如何socket发送方没有做socket重连的话,会导致服务的崩溃。
  • 我们可以实时检测是否有 readyState ===2 或者 readyState ===3 的socket连接,主动去执行ws.terminate(),因为在实战的过程中,发现某个socket状态持续为 2(即closing),而不是3(closed)

最后 放上两个websocket的nodejs的框架

1 https://socket.io/

  1. https://github.com/websockets/ws

你可能感兴趣的:(websocket中Node.js中的应用)