通过 WS 与 Http 发送多个 5mb 二进制文件
在发送大文件时,通过 Websocket 发送大文件是否会“阻止”Websocket 发送其他消息?
通过独立的 Http 请求发送文件,同时继续通过 WS 发送其他消息是否具有“保持 WS 畅通无阻”的明显优势?
假设有 1 个网卡。
Does sending large files over a websocket "block" websocket for other messages while the large files are being sent?
Does sending the files via independent Http requests while the other messages continue to be sent over WS have any distinct advantage "in keeping the WS unblocked"?
Assume 1 network card.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对于基于 HTTP/1.1 的 WebSocket,是的,上传大文件(以大 WebSocket 消息的形式)会阻塞 WebSocket 连接。
如果是 WebSocket over HTTP/2(如果客户端和服务器都支持),则一HTTP/2 流将上传大文件,另一个 HTTP/2 流用于携带 WebSocket 消息。在这种情况下,问题就变成了 HTTP/2 流量控制窗口,该窗口可能会被大的上传流耗尽,从而导致 WebSocket 消息流停滞(从而导致消息排队和延迟)。不幸的是,此排队/延迟的详细信息取决于客户端和服务器实现,因此您必须尝试。
通常,实现在交错流方面做得很好,因此可能的停顿很少成为问题。
对于 HTTP/1.1 上的 WebSocket,如果打开多个 WebSocket 连接,则可以使用文件的
N
个 WebSocket 连接和1
并行发送文件和消息例如,用于消息的 WebSocket 连接。一些非浏览器客户端允许您打开到同一域的多个 HTTP/2 连接,因此您将有机会并行发送文件和消息。然而,据我所知,浏览器不允许超过 1 个 HTTP/2 连接到同一域,因此并行性是存在的,但受到 HTTP/2 流量控制窗口的限制。
不确定“保持 WS 畅通”是什么意思,但 HTTP/1.1 的工作方式与 WebSocket 的连接使用方式相同。
如果您处于浏览器环境中,则浏览器允许同一个域有 6-8 个 HTTP 连接,并且通常允许无限制(或至少更多)的 WebSocket 连接。
因此,如果您要发送(例如)10 个大文件,其中 6-8 个将通过 HTTP 上传,但其余的将排队等待其中一个 HTTP 连接完成前一个上传。
同时,您可以使用WebSocket连接发送消息。
在 HTTP/2 的情况下,浏览器仅打开 1 个连接,因此您可以使用 HTTP/2 流进行上传,并使用 HTTP/2 流上的 WebSocket 进行消息,但它们都将共享相同的 HTTP/2 流控制窗口,可能会互相拖延。
总而言之,WebSocket 并不是为大型上传而设计的。
如果您达到 WebSocket 消息大小限制,我不会感到惊讶,因为服务器不允许客户端上传任意大小的消息(因为这会耗尽服务器内存)。对于客户来说也是如此;浏览器通常对它们接收的 WebSocket 消息的大小有较小的限制,无论使用的是 HTTP/1.1 还是 HTTP/2。
如果您确实需要上传大文件,我认为通过 HTTP 上传(允许更大的大小,例如使用
multipart/form-data
时)并通过 WebSocket 保留小消息传递的解决方案是最佳选择。使用 HTTP/2可能会达到 HTTP/2 流量控制窗口限制,但 HTTP/1.1 中也有 6-8 个连接的限制,因此您必须再次尝试查看 >如果你达到了任何限制,如果达到了,在什么情况下是哪个限制。
使用 HTTP 进行上传可以降低您遇到事先未知的 WebSocket 消息大小限制的可能性,这些限制可能因客户端(浏览器到浏览器)而异,并且您不想通过以下方式实现自己的大型上传的拆分和合并WebSocket 尊重这些限制。
In case of WebSocket over HTTP/1.1, yes, the upload of a large file (in the form of a large WebSocket message) blocks the WebSocket connection.
In case of WebSocket over HTTP/2 (if supported by both the client and server), one HTTP/2 stream will upload the large file, and another HTTP/2 stream is be used to carry WebSocket messages. In this case, the problem becomes the HTTP/2 flow control window, which may be exhausted by the large upload stream, leaving the WebSocket message stream stalled (so that messages are queued and delayed). Unfortunately, the details of this queueing/delay depend on the client and on the server implementations, so you have to try.
Typically implementations do a good job at interleaving streams, so rarely the possible stalls are a problem.
For WebSocket over HTTP/1.1, if you open multiple WebSocket connections, you may be able to send files and messages in parallel, using
N
WebSocket connections for the files, and1
WebSocket connection for the messages, for example.Some non-browser clients allow you to open multiple HTTP/2 connections to the same domain, so again you will have the chance to send files and messages in parallel. However, to my knowledge, browsers do not allow more than 1 HTTP/2 connection to the same domain, so the parallelism is there, but constrained by the HTTP/2 flow control window.
Not sure what you mean by "keeping the WS unblocked", but HTTP/1.1 works in the same way as WebSocket for what pertains its usage of connections.
If you are in a browser environment, browsers allow 6-8 HTTP connections to the same domain, and typically unlimited (or at least many more) WebSocket connections.
So if you want to send, say, 10 large files, 6-8 of them will be uploaded via HTTP, but the remaining will be queued waiting for one of the HTTP connections to finish the previous upload.
Meanwhile, you can use the WebSocket connection to send messages.
In case of HTTP/2, browsers only open 1 connection, so you may use HTTP/2 streams for the uploads and a WebSocket over HTTP/2 stream for the messages, but they will all share the same HTTP/2 flow control window, potentially stalling each other.
All in all, WebSocket has not been designed for large uploads.
I would not be surprised if you hit WebSocket message size limits, as servers cannot allow clients to upload messages of arbitrary size (as it will blow up the server memory). The same is true for clients; browsers have typically small limits for the size of WebSocket messages that they receive, independently of whether HTTP/1.1 or HTTP/2 is used.
If you really need to upload large files, I think a solution where you upload via HTTP (which allow larger sizes, for example when using
multipart/form-data
), and keep small messaging via WebSocket is optimal.The use of HTTP/2 may hit the HTTP/2 flow control window limit, but you have a limit in 6-8 connections in HTTP/1.1 too, so again you have to try and see if you hit any limit, and if you do, which limit it is in what case.
Using HTTP for uploads makes less likely that you hit WebSocket message size limits that are not known in advance and possibly different from client to client (browser to browser), and you don't want to implement your own splitting and merging of large uploads via WebSocket to respect those limits.