我正在和同事一起讨论Websocket的开销,我们都不确定Websocket如何实际检测到客户端连接的状态。
我很惊讶我无法在SO上找到答案,但这可能是我的错误。我发现this answer解决了可扩展性问题,但这不是我在这里提出的问题。 This answer触及了实施,但并不是我在这里所追求的深度。
答案 0 :(得分:4)
webSocket连接是使用webSocket协议的TCP连接。默认情况下,只有当底层TCP意识到连接已关闭并且webSocket层正在侦听连接上的close事件时,服务器或客户端才知道连接何时消失,以便通知该方式。
webSocket协议本身不需要心跳包,可以定期测试连接是否仍在工作。 TCP套接字可能仍然显示为活动,但实际上连接可能仍然无法正常工作。另一端可能已经消失或中断,一个或两个端点可能在任何给定时间都不知道。
Socket.io构建于webSocket之上,使用ping和pong数据包实现心跳,定期测试连接,实际上会检测客户端的无效连接,关闭套接字然后自动重新连接。
是否有"状态"数据包定期发送到客户端/服务器?
默认情况下,不是常规的webSocket连接。
它与低级API中的ping或pong有什么关系吗?
如果客户端或服务器想要发送ping或pong数据包以实现某种连接验证检测,则由客户端或服务器决定。
框架怎么样?
webSocket框架是通过webSocket发送数据的数据格式。他们与这个问题没有任何关系。
Websocket如何检测到它在客户端上断开连接?服务器?
如上所述。除非客户端/服务器实现自己的ping / pong系统来检测连接何时出错,否则它们只依靠TCP信令来知道连接何时被另一端关闭。在客户端或服务器尝试发送之前,webSocket连接可能无法正常运行。
当浏览器窗口/选项卡打开webSocket连接,然后窗口/选项卡重新定位到新URL时,浏览器将关闭与该窗口/选项卡关联的所有资源,包括任何webSocket连接。如果客户端和服务器之间的链接在那时起作用,那么服务器将被告知底层TCP连接(因此webSocket)已被关闭。如果网络链接断开然后用户将该窗口/选项卡移动到新URL,则服务器不一定知道连接不起作用而不依赖于ping / pong类型信令来定期测试连接。
如果浏览器崩溃,操作系统应该关闭该进程打开的任何套接字。
如果计算机/操作系统崩溃,套接字可能无法正常关闭(尽管这可能与操作系统有关,也可能与崩溃有关)。