什么时候最好使用 ws.terminate() VS ws.close()

Dra*_*ena 1 javascript websocket node.js ws

我知道终止硬关闭套接字不会让它挂起或像 close 那样发送更多数据包,并且终止在关闭套接字时发送不同的代码(1006 与 close 发送 1000)。所以这就提出了一个问题,当我不打算重新打开套接字时,为什么我还要使用 ws.close() ?我见过很多只使用 ws.close() 并且从不重新打开它的例子。它只是不为人所知或不标准,或者幕后有什么我不知道的吗?

Ber*_*rgi 6

  • 关闭 Web 套接字将等待缓冲的消息完成,并启动关闭握手。这包括可选的关闭代码和可选的关闭原因。它告诉客户端 websocket 现在已关闭,不会再发送任何消息,一旦另一端确认,tcp 连接将关闭。参见1.4结束握手

    关闭握手旨在补充 TCP 关闭握手 (FIN/ACK),因为 TCP 关闭握手并不总是端到端可靠,尤其是在存在拦截代理和其他中介的情况下。

    通过发送关闭帧并等待关闭帧响应,可以避免某些可能不必要地丢失数据的情况。例如,在某些平台上,如果套接字在接收队列中有数据时关闭,则会发送 RST 数据包,这将导致接收 RST 的一方的 receive() 失败,即使有数据等待发送读。

    这被认为是一个干净的关闭。关闭代码通知另一端的状态,如果省略,则导致状态 1005。

  • 终止网络套接字只会断开连接。它调用socket.destroy(),没有发送关闭帧或任何东西,甚至没有用 FIN 干净地关闭 tcp 连接。这会导致另一端在超时后出现状态1006。

在协议中进行关闭握手的缺点是,当另一端根本不再响应时,关闭连接可能会处于悬而未决的状态。只有暂停才能结束这一切,并带来 各种 问题

ws.close()当我不打算重新打开套接字时为什么还要使用?

您应该始终优雅地使用close()Web 套接字来通知另一端连接已结束。您还应该发送关闭原因 1000(作为客户端)或 1001(作为服务器)以告诉另一端他们不应尝试重新连接。

如果服务器需要断开连接但很快就会再次可用,则它可能会强制关闭 TCP 连接。这将导致客户端立即检测到异常关闭,并且可能会在短时间内尝试自动重新连接。(库中没有方法可以执行此操作ws,您必须调用ws._socket.end())。

如果您的terminate()连接正常,另一端将不会注意到任何事情。只有当它尝试发送某些内容(例如 a ping())时,经过一段时间后,它才会发现 tcp 连接丢失,并且 websocket 会异常关闭。不要那样做!

terminate()仅当您确定连接已经丢失时才应调用(就像心跳示例中那样) 。这将快速释放您一端的资源,并立即触发对象上的相应流事件ws