我们有一个使用toronto编写的服务器,它通过websocket向客户端发送异步消息。在这种情况下,在Mac上的Chrome中运行的javascript应用程序。当客户端被强制断开连接时,在这种情况下,通过使客户端进入睡眠状态,服务器仍然认为它在向客户端发送消息。此外,当客户端从睡眠中醒来时,消息会以突发的方式传递。
这些消息的排队/缓冲机制是什么?谁负责?为什么它们仍在交付?谁在重新连接插座?我的直觉是,即使WebSocket不像HTTP那样是请求/响应,但它们仍然需要ACK数据包,因为它们是基于TCP构建的。这样做是为了使协议对移动时代的暂时下降更加稳健吗?
浏览器可以在一个单独的线程中处理websocket客户端消息,该线程不会被睡眠阻止。
即使自定义应用程序的某个线程未处于活动状态,当您强制它休眠时(如sleep(100)),TCP连接在这种情况下也不会关闭。套接字句柄仍然由操作系统内核管理,TCP服务器仍然发送消息,直到到达TCP客户端的接收窗口溢出。即使在这之后,服务器端的应用程序仍然可以成功地提交新消息,这些消息在服务器端的TCP级别上进行缓冲,直到TCP传出缓冲区溢出为止。当传出缓冲区已满时,应用程序应该在发送请求时得到错误代码,比如"没有更多空间"。我没有试过,但它应该这样。
尝试关闭客户端(终止进程),你会看到完全不同的画面——服务器会注意到断开连接。
对于高度可靠的场景,断开连接和溢出这两种情况在服务器端都很难处理。断开连接的情况可以转换为溢出情况(当客户端重新连接时,websocket服务器可以在用户空间上缓冲消息,达到一定的限制)。然而,并没有简单的方法来可靠地处理传输缓冲区限制的溢出。我只看到一个解决方案——将溢出错误传播回事件的发起方,该事件引发了由于溢出而被丢弃的消息。