为了账号安全,请及时绑定邮箱和手机立即绑定

基于“广播”或“房间”的 Websocket 策略

基于“广播”或“房间”的 Websocket 策略

Go
慕雪6442864 2022-06-01 18:10:14
基于“房间”的 WebSocket 连接或 WebSocket 中的“广播”选项背后的技术或策略是什么?我们是否将“用户的 WebSocket 连接 ID”存储在基于房间的聊天系统的特定列表中?在发送时,我们是否使用 for 循环向每个参与者/WebSocket-Connection-ID“发送/接收”消息,或者我们是否有一个 API 可以在不使用循环的情况下一次性向所有组用户发送消息?我正在使用“大猩猩 WebSocket” - https://github.com/gorilla/websocketfor loop如果我们将 WS 连接 ID 存储在一个列表中,那么如果任何房间增加了 5000 个参与者,那么运行一个为每个参与者发送/接收消息将变得非常麻烦。请不要共享任何库,我想了解基于房间的聊天系统如何工作或在后端运行?
查看完整描述

3 回答

?
胡子哥哥

TA贡献1825条经验 获得超6个赞

如果您使用uWebSockets,则有订阅/发布机制。我不确定这种机制是否适用于所有支持 WebSockets 的服务器端框架。

这个想法很简单。您将 WebSocket 订阅到某个“主题”,并且您可以向属于该特定主题的用户发布消息。

当您检查源代码时,它会在内部循环它调用的内容WebSocketContextData。当您从 TCP 套接字的角度考虑它时,这是有道理的。那里的每个协议都建立在 TCP 或 UDP 之上。


查看完整回答
反对 回复 2022-06-01
?
qq_花开花谢_0

TA贡献1835条经验 获得超7个赞

我用这种技术构建了一个 web-socket ,但对其进行了一些修改以支持多房间。

我为每个房间创建了一个集线器,并将集线器的地址存储在地图中,其中键为字符串,以便更轻松地使用房间名称访问每个集线器。

现在,上面提供的链接是包含在 gorilla/websocket 库中的官方示例,他们还清楚地记录了它的运行和行为方式。我建议您阅读该链接以更好地理解该示例。

我将尝试简短地解释它。

存储聊天室中人员列表的集线器作为常规运行。每个用户将被分配 2 个 go 例程,一个用于接收传入消息,一个用于将消息发送回它的客户端。除此之外,每个用户都有几个无缓冲的通道来存储已接收或要发送的数据。

假设我发送一条消息,负责读取的 go-routine 读取消息并将其传递到它与集线器之间共享的通道。现在,集线器需要将消息广播给聊天室中的每个人。它简单地遍历列表用户并使用通道(再次,但不同的通道,而不是之前的通道)将数据传递给负责发送消息的每个 go-routine。

请记住,我的解释只是一个概述,还有很多细节我没有写,因为除非你仔细阅读代码,否则我很难理解,但我错过的事情是给出示例的文档,所以请随意参考那个。

现在回到 5000 名参与者的问题。如果他们不同时发送消息,上述方法可以轻松处理,这不太可能。我在负载测试期间遇到了类似的问题,并且很困惑为什么我的连接会崩溃。

事实证明,无缓冲通道是一个问题,将其更改为缓冲通道(缓冲区的大小取决于同时消息的数量)。

因此,即使有 5000 名参与者,集线器也只需要使用通道传递消息,而两个 go-routines 会完成繁重的工作。

PS:我想对消息进行任何检查,或者数据库操作,然后在 read go-routine 上进行,而不是在集线器中阻止其他消息。


查看完整回答
反对 回复 2022-06-01
?
哈士奇WWW

TA贡献1799条经验 获得超6个赞

websockets 上没有向所有用户“广播”,您必须单独运行每个用户。这在每个库中都是一样的,您可以查看“uWebSockets”,这可能是存在的最快的 websocket 代码,它也必须这样做。有些人可以通过共享内存缓冲区和零内存分配来做到这一点,并且运行效率非常高。但是你仍然需要遍历每个人。



查看完整回答
反对 回复 2022-06-01
  • 3 回答
  • 0 关注
  • 225 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信