3 回答
TA贡献1825条经验 获得超6个赞
如果您使用uWebSockets
,则有订阅/发布机制。我不确定这种机制是否适用于所有支持 WebSockets 的服务器端框架。
这个想法很简单。您将 WebSocket 订阅到某个“主题”,并且您可以向属于该特定主题的用户发布消息。
当您检查源代码时,它会在内部循环它调用的内容WebSocketContextData
。当您从 TCP 套接字的角度考虑它时,这是有道理的。那里的每个协议都建立在 TCP 或 UDP 之上。
TA贡献1835条经验 获得超7个赞
我用这种技术构建了一个 web-socket ,但对其进行了一些修改以支持多房间。
我为每个房间创建了一个集线器,并将集线器的地址存储在地图中,其中键为字符串,以便更轻松地使用房间名称访问每个集线器。
现在,上面提供的链接是包含在 gorilla/websocket 库中的官方示例,他们还清楚地记录了它的运行和行为方式。我建议您阅读该链接以更好地理解该示例。
我将尝试简短地解释它。
存储聊天室中人员列表的集线器作为常规运行。每个用户将被分配 2 个 go 例程,一个用于接收传入消息,一个用于将消息发送回它的客户端。除此之外,每个用户都有几个无缓冲的通道来存储已接收或要发送的数据。
假设我发送一条消息,负责读取的 go-routine 读取消息并将其传递到它与集线器之间共享的通道。现在,集线器需要将消息广播给聊天室中的每个人。它简单地遍历列表用户并使用通道(再次,但不同的通道,而不是之前的通道)将数据传递给负责发送消息的每个 go-routine。
请记住,我的解释只是一个概述,还有很多细节我没有写,因为除非你仔细阅读代码,否则我很难理解,但我错过的事情是给出示例的文档,所以请随意参考那个。
现在回到 5000 名参与者的问题。如果他们不同时发送消息,上述方法可以轻松处理,这不太可能。我在负载测试期间遇到了类似的问题,并且很困惑为什么我的连接会崩溃。
事实证明,无缓冲通道是一个问题,将其更改为缓冲通道(缓冲区的大小取决于同时消息的数量)。
因此,即使有 5000 名参与者,集线器也只需要使用通道传递消息,而两个 go-routines 会完成繁重的工作。
PS:我想对消息进行任何检查,或者数据库操作,然后在 read go-routine 上进行,而不是在集线器中阻止其他消息。
TA贡献1799条经验 获得超6个赞
websockets 上没有向所有用户“广播”,您必须单独运行每个用户。这在每个库中都是一样的,您可以查看“uWebSockets”,这可能是存在的最快的 websocket 代码,它也必须这样做。有些人可以通过共享内存缓冲区和零内存分配来做到这一点,并且运行效率非常高。但是你仍然需要遍历每个人。
- 3 回答
- 0 关注
- 225 浏览
添加回答
举报