gpt4 book ai didi

python - 使用 redis-py 更改 PubSub 订阅

转载 作者:IT王子 更新时间:2023-10-29 06:02:55 24 4
gpt4 key购买 nike

我有一个实时 Web 应用程序,其中客户端从多个 Redis PubSub channel 接收更新,使用 gevent-socketio 和 redis-py 构建。

我正在查看 views.py, l.26django-tictactoe例子。当客户端为 channel 发送订阅消息时,它会生成一个新的 greenlet。然后 greenlet 订阅 Redis PubSub channel 并阻塞,直到收到消息。

class GameNamespace(BaseNamespace):
def listener(self, chan):
red = redis.StrictRedis(REDIS_HOST)
red = red.pubsub()
red.subscribe(chan)

print 'subscribed on chan ', chan

while True:
for i in red.listen():
self.send({'message': i}, json=True)

def recv_message(self, message):
action, pk = message.split(':')

if action == 'subscribe':
Greenlet.spawn(self.listener, pk)

据我所知,如果不产生新的 Greenlets 或取消订阅,就不可能添加订阅。

您将如何有效地处理频繁的订阅和取消订阅?

更新:我正在构建的是一个理论上无限的 2D map 上的 HTML5 实时 MMO 游戏。由于 map 的大小,不可能将整个 map 的状态发送给浏览器。因此, map 被划分为多个图 block ,这些图 block 会在玩家拖动 map 时动态加载(想想 Google map )。

每当拖动 map 时,客户端/浏览器都会订阅刚刚变得可见的图 block 的更新,并在短暂的延迟后取消订阅变得不可见的图 block 的更新。对订阅的更改可能每个玩家每秒发生一次,因此频繁是相对的。

客户数量(希望)会很大。理论上,所有玩家都可以查看 map 的同一部分,使得 SUBSCRIBEUNSUBSCRIBE非常昂贵,因为它们是“O(N),其中 N 是已经订阅 channel 的客户数量”。实际上,它会均匀地分布在世界各地,所以这应该不是问题。

但是,我的主要问题是 Python Redis PubSub 实现在监听时阻塞。在上面的示例中调用 red.listen() 后,我无法再更改订阅,直到一条消息到达。上面的示例代码启动了一个新的 Greenlet,每个订阅都有一个到 Redis 的新连接,这可能是个坏主意。

最佳答案

您没有说明跨订阅的分区基本原理/要求是什么,即哪些信息流过订阅必须与其他订阅分开,因此很难给出明确的答案。我会做出一些假设...

如果您有少量或固定数量的客户端管理多个订阅,则最好通过单个长期订阅多路复用多个不同的事件,由该 Redis 客户端对最终的事件消费者进行多路分解。从 Redis 的角度来看,这种方法可能比为每个消费者重复设置和取消订阅更高效。

像这样的方案需要发布者提供一些额外的智能,以便他们可以为每条消息选择正确的队列,但这有时很容易实现,例如通过散列客户端 ID 模 N,其中 N 是发布/订阅队列的数量。

我希望这与您询问的内容有关...

关于python - 使用 redis-py 更改 PubSub 订阅,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10232824/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com