我可以通过 socket.emit 发送多少数据?

Posted

技术标签:

【中文标题】我可以通过 socket.emit 发送多少数据?【英文标题】:How much data can I send through a socket.emit? 【发布时间】:2012-10-10 06:32:55 【问题描述】:

所以我使用的是 node.js 和 socket.io。我有一个小程序,它获取文本框的内容并将其发送到 node.js 服务器。然后,服务器将其转发回其他连接的客户端。有点像聊天服务,但不完全是。

无论如何,如果用户输入价值 2-10k 的文本并尝试发送它会怎样?我知道我可以自己尝试一下,但我正在寻找一个实用的最佳实践限制,以限制我可以通过发射处理多少数据。

【问题讨论】:

您可以发送任意数量的数据。即使是大视频文件。这里唯一的问题是可扩展性,即你想向多少用户广播它?但无论如何你都会遇到这类问题。 当我将 20Mb 文件数据作为 base64 编码字符串发出时,房间内的其他人能够接收但如果超过 23MB 文件数据则无法接收.. 有什么解决方案适合我 【参考方案1】:

从 v3 开始,socket.io 的默认消息限制为 1 MB。如果消息大于该值,则连接将被终止。

您可以通过指定 maxHttpBufferSize option 来更改此默认值,但请考虑以下内容(最初是十多年前编写的,但仍然适用):

节点 和 socket.io 没有任何内置限制。您确实需要担心的是消息大小、每秒发送的消息数量、连接的客户端数量以及服务器可用带宽之间的关系——换句话说,没有简单的答案。

让我们考虑一条 10 kB 的消息。当有 10 个客户端连接时,您的服务器必须推送 100 kB 的数据,这是完全合理的。添加更多客户端,要求很快就会变得更高:10 kB * 5,000 个客户端 = 50 MB。

当然,您还必须考虑协议开销的数量:每个数据包,TCP 增加约 20 字节,IP 增加 20 字节,以太网增加 14 字节,总共 54 字节。假设 MTU 为 1500 字节,您正在查看每个客户端 8 个数据包(不考虑重传)。这意味着您将通过网络发送 8*54=432 字节的开销 + 10 kB 有效负载 = 每个客户端 10,672 字节。

10.4 kB * 5000 个客户端 = 50.8 MB。

在 100 Mbps 的链路上,理论最小值可以向 5,000 个客户发送 10 kB 的消息如果您能够饱和链接。当然,在丢包和损坏数据需要重新传输的现实世界中,这将需要更长的时间。

即使将 10 kB 发送给 5000 个客户需要 8 秒的非常保守的估计,但在每 10-20 秒发送一条消息的聊天室中,这可能还不错。

所以说真的,归结为几个问题,按重要性排序:

    您的服务器将有多少带宽可用? 将同时连接多少用户? 每分钟将发送多少条消息?

回答完这些问题后,您可以确定您的基础架构将支持的最大消息大小。

【讨论】:

这是一个很棒的答案。感谢您在较低级别进行解释。但是每个客户端的 8 个数据包是从哪里来的呢?此外,出于某种原因,我认为套接字有 512 个字节或类似的限制。不知道我从哪里得到的。哈哈。谢谢 对于 1500 B 的以太网 MTU,每个数据包的最大有效负载大小为 1500 B - 40 B(TCP+IP 开销)= 1460 B。要发送 10,240 B 的数据,最少 8必须发送数据包(1460*7 = 10220 - 不够;还有 20 个字节要发送。1460*8 = 11,680)。 太棒了。这 8 个数据包是同时发送还是串行发送?还是以某种随机顺序?我知道这有点过时,但我很欣赏这个答案。 :-) 就其本质而言,数据包是串行发送的——所有数据都必须以字节流的形式发送。由于 IP 路由的性质,这些数据包可能不会以正确的顺序到达,但您永远不必担心这一点,因为 TCP 的工作是确保数据包在之前重新组合成正确的顺序将数据交给应用程序。 FALSE , 有 1M 的限制,阅读更多:socket.io/docs/v4/troubleshooting-connection-issues/…【参考方案2】:

2-10k 很好,没有任何强制限制或任何东西,它只是归结为带宽和实用性.. 10k 虽然在宏伟的计划中很小,所以如果这有点高,你应该没问题给你。

【讨论】:

CPU 也可能是瓶颈。我假设每个人都忽略了 CPU,因为他的消息很大而且很少见。导致网络瓶颈首先出现...【参考方案3】:

限制 = 1M默认

使用此示例配置为 ma​​xHttpBufferSize 指定自定义限制:

const io = require("socket.io")(server, 
    maxHttpBufferSize: 1e8, pingTimeout: 60000
);
1e8 = 100,000,000 :这对于任何大规模响应/发射都有好处 pingTimeout : 当发射量很大时,需要时间,你也需要增加 pingtime

阅读更多来自Socket.IO Docs

这些设置之后,如果您的问题仍然存在,那么您可以检查相关的代理网络服务器配置,例如 client_max_body_size限制速率 in nginx(如果您有与 socketIO 应用相关的 http 代理)或客户端/服务器 防火墙 规则。

【讨论】:

以上是关于我可以通过 socket.emit 发送多少数据?的主要内容,如果未能解决你的问题,请参考以下文章

Socket.emit 不发送或 socket.on 不接收?

Node.js 到 C++ 客户端:未从 socket.emit 接收消息

socket中 emit和on的写法

NESTJS 网关/Websocket - 如何通过 socket.emit 发送 jwt access_token

如果几乎同时发送Socket.io'组合'数据包吗?

socket.io 没有发送给所有客户端