Websocket阻止来自服务器的传入请求

Posted

技术标签:

【中文标题】Websocket阻止来自服务器的传入请求【英文标题】:Websocket blocking incoming request from server 【发布时间】:2016-06-03 05:53:35 【问题描述】:

配置

我有一个使用 websockets 连接到服务器的 java 客户端。我正在使用 netty 框架作为 websocket 实现。服务器向客户端发送ping,客户端以pong帧响应,否则将导致服务器关闭连接。

场景

我的客户端向服务器发送多个请求并期望得到响应。现在如果第一个请求的响应很大,那么后面的响应和 ping 都会被阻塞,直到客户端完全下载第一个请求。由于 ping 也被阻止,服务器假定连接已断开并强制关闭套接字,客户端必须重新连接并再次发送 2 个请求,因为上次响应未完成。

问题

有没有办法使 websocket 以非阻塞方式运行,以便可以处理其他响应/ping?

【问题讨论】:

听起来你的 ping 间隔太短了。您发送的消息有多大?发送和接收它们需要多长时间?它是 TCP,因此数据是串行发送的。在发送并确认其前面的大数据之前,实际上不会通过线路发送 ping。如果这需要很长时间,那么您需要放慢速度,不要在之前的大数据仍在发送时立即尝试发送 ping。 目前是 90 秒。但这没关系,因为即使我增加它,我也无法控制客户端的下载速度,比如说图像。图片大小也不能控制。 那么,可能是你的webSocket库有问题。在发送前一条消息后的某个重要时间之前,它不需要尝试发送 ping。你还希望我们说什么。它不应该在刚刚发送消息后立即发送 ping。只有在发送先前的数据后一段时间不活动后,ping 才会消失,并且该时间需要足够长,以使任何潜在或慢速客户端都能够响应。这就是 ping/pong 系统需要如何工作才能有效且不会出现误报。 您要发送多大的图像?我认为您应该向客户端发送一个 URL,并让浏览器使用该 URL 通过 HTTP 请求图像,并从您的 websocket 中获取图像位,从而解决整个问题。 webSocket 并不是真正设计成一个下载系统。虽然可以将它用于很多事情,但它具有优势和不那么优势。较小的有效负载不会干扰同一通道的其他用途并且不会导致 ping 问题,这会好得多。 通过 http 下载图片是一个有效的解决方案。客户端可能正在使用不可靠的 2G 移动连接,并且可能会有跨越几千字节 json 的响应。如果连接物理中断,客户端也不会收到其他请求的响应,这将再次重试。 【参考方案1】:

有没有办法让 websocket 以非阻塞方式运行,所以 可以处理其他响应/ping 吗?

不是真的。 webSocket 是底层的 TCP 套接字。 TCP 套接字串行发送数据。如果您要发送大量数据,则必须先交付所有数据,然后才能交付其后面的数据包。这就是 TCP 的工作原理。为了解决这个问题,当浏览器想要一次下载多个内容或防止下载一个较大的内容影响其同时执行其他操作的能力时,它会使用多个 TCP 连接。

我认为 webSocket 并不是通过慢速链接发送大图像文件的理想传输方式 - 特别是当您有 ping 和其他数据时,您希望通过 webSocket 获得一些响应。

可能更好的方案是通过 webSocket 发送一个 URL,然后让客户端在收到 URL 时通过不同的 HTTP 请求请求该图像。然后,您仅将 webSocket 用于较小的控制消息,而大型数据传输通过并行 HTTP 连接进行,不会干扰继续将 webSocket 连接用于其他事情(如 ping 或其他控制消息)的能力。

而且,您知道 HTTP、浏览器和网络服务器已经针对提供图像进行了高度优化(因为除了视频之外,它们的大部分带宽使用量都是如此)。

【讨论】:

以上是关于Websocket阻止来自服务器的传入请求的主要内容,如果未能解决你的问题,请参考以下文章

WebSocket 服务器如何处理多个传入的连接请求?

端口 80 被 ISP 阻止 [关闭]

如何检测从 Websocket 服务器发送的消息

Web 服务器如何在单个端口 (80) 上一次处理多个用户的传入请求?

WebSocketSocketTCPHTTP区别

Nginx ingress pod在传入的websocket连接请求中返回404