go - 基于 "Broadcast"或 "Room"的 Websocket 策略

标签 go websocket uwebsockets

房间”基于WebSocket连接或“广播”选项背后的技术或策略是什么?

我们是否将“用户的 WebSocket 连接 ID”存储在基于房间的聊天系统的特定列表中?
在发送时,我们是否使用 for 循环向每个参与者/WebSocket-Connection-ID“发送/接收”消息,或者我们是否有一个 API 可以在不使用循环的情况下一次性向所有组用户发送消息?

我正在使用“gorilla WebSocket”-https://github.com/gorilla/websocket

如果我们将 WS 连接 ID 存储在一个列表中,那么如果任何房间增加了 5000 个参与者,那么运行 for loop 将变得非常错误。为每个参与者发送/接收消息。

请不要共享任何库,我想了解基于房间的聊天系统如何工作或在后端运行 ?

最佳答案

我建立了一个网络套接字this技术,但对其进行了一些修改以支持多房间。

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

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

我将尝试简短地解释它。

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

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

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

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

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

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

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

关于go - 基于 "Broadcast"或 "Room"的 Websocket 策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61789964/

相关文章:

go - 填充缓冲 channel 直到变满或持续时间过去

go - 读取任意数量的输入标准输入

rest - 在 Golang 中向 Splunk REST API/search/jobs/endpoint 发送查询

javascript - 实时 : Websockets vs Comet

javascript - Socket io,JavaScript 数据未在表中更新自身

javascript - 检查客户端是否有 socket.io id 仍然连接

c++ - 从另一个线程向 uWebSockets 0.15.x 套接字发送数据

go - 两种不同语言之间的 Protocol Buffer

c++ - 如何修复 OSX 中“找不到 "fatal error: ' sys/epoll.h”文件?