让频道与 Python-socketio 中的房间一致,以及一般的 pubsub 问题

Posted

技术标签:

【中文标题】让频道与 Python-socketio 中的房间一致,以及一般的 pubsub 问题【英文标题】:Have channels coincide with rooms in Python-socketio, and general pubsub questions 【发布时间】:2021-11-10 22:56:50 【问题描述】:

我正在使用 python-socketio 处理一个涉及 websockets 的项目。 我们主要关心的是流动性,每个连接的用户都会有一个光标,其在板上的位置每 50 毫秒作为事件发送一次,板被标识为(套接字)房间,我们期待其中的许多。

我是 PubSub 的新手,我们正在横向扩展我们的架构,它似乎适合事件广播。

我查看了 AsyncRedisManager 类,据我了解,似乎 any 消息,由 any socketio 上的 any 套接字发送服务器(带有 pub/sub)然后通过 single 通信通道从该服务器传输/发布到 redis。然后,此频道的订阅者可以看到此消息流。

因此我担心三件事:

由于所有消息都只是通过一个通道,这不是“设计缺陷”吗,因为某些服务器可能没有连接到“一个”特定房间的套接字(目前),但它们仍然会接收(并且 pickle .loading),他们当时并不关心的消息。 这些消息的实际详细信息(房间、有效负载等)由服务器pickled.dumped 和pickle.loaded。如果有 50 个房间,每个房间有 50 个游标,每个房间发送 25 个事件/秒,这会不会是一个巨大的 CPU 限制瓶颈? 我正在研究 socket.io 文档,将 redis 适配器与 Python-socketio pubsub 管理器并排比较,似乎通道是动态命名空间的,如“socketio#room_name”和广播到这些“命名空间”的消息” 频道,因此 psubscribe 将是一个可行的解决方案。其他一些 MQ 以“主题”的形式引用。 如果前一个假设是正确的,我们仍然不能假设一台服务器是否应该订阅频道#room_name,除非房间中没有或至少有一个用于该服务器的套接字。

我理解 pub/sub 的范式是,来自 Redis 页面:

相反,发布的消息被描述为频道,而不知道可能有哪些订阅者(如果有的话)。订阅者对一个或多个频道表示兴趣,并且只接收感兴趣的消息,而不知道有哪些(如果有)发布者。

但我的问题可以概括为: 是否可以让 Python-socketio 服务器在需要时动态订阅/取消订阅频道,将频道标识为房间,因此总共有与房间一样多的频道。在将这种“即插即用”的简单逻辑保留为 pubsubManager 子类的同时,这是否可行?我是否遗漏了什么或者这有意义吗?

感谢您的宝贵时间,任何想法、更正或“草稿”代码将不胜感激。

【问题讨论】:

【参考方案1】:

是否可以让 Python-socketio 服务器在需要时动态订阅/取消订阅频道,并将频道标识为房间

我想这是可能的,使用自定义客户端管理器类。您需要从现有的客户端管理器或基本客户端管理器之一继承,并实现适合您需要的不同发布/订阅逻辑。但请记住,如果您有 10,000 个客户,那么至少会有 10,000 个房间,因为每个客户都有一个私人房间。

【讨论】:

嘿@Miguel!感谢您的回答,您的意见对我来说非常宝贵。很抱歉非常坚持,但是我以前对您的代码的假设是否正确?只是想确定我明白了。另外,在那种情况下,我想我需要在同一个客户端管理器中创建许多 self.pubs / self.subs,因为我认为不可能在 socketio.AsyncServer 的构造函数中“附加”许多 client_managers ?最后,关于何时计划迁移到 aioredis2 支持的任何愿景?愿意贡献。谢谢! 如果你问我是否同意当前的方法是一个“设计缺陷”,那么不,我不同意。但如果这种类型的解决方案更适合您的需求,那么正如我在回答中所说,您完全可以实现自己的发布/订阅机制。

以上是关于让频道与 Python-socketio 中的房间一致,以及一般的 pubsub 问题的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Flask 和 Socket.io 加入和离开房间的简明示例?

使用http-kit和Clojure处理“房间”

如何让模型验证与 Rails 中的视图层对话以提供简单的功能?

如何在线程中运行 python-socketio?

python-socketio 文档翻译

如何将 Android 应用程序连接到 python-socketio 后端?