Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用redis py更改PubSub订阅_Python_Redis_Socket.io_Publish Subscribe_Gevent - Fatal编程技术网

Python 使用redis py更改PubSub订阅

Python 使用redis py更改PubSub订阅,python,redis,socket.io,publish-subscribe,gevent,Python,Redis,Socket.io,Publish Subscribe,Gevent,我有一个实时webapp,客户端从多个Redis PubSub频道接收更新,这些频道由gevent socketio和Redis py构建 我正在看示例中的。 当客户端为某个频道发送订阅消息时,它会生成一个新的greenlet。greenlet然后订阅Redis PubSub频道并阻塞,直到收到消息 class GameNamespace(BaseNamespace): def listener(self, chan): red = redis.StrictRed

我有一个实时webapp,客户端从多个Redis PubSub频道接收更新,这些频道由gevent socketio和Redis py构建

我正在看示例中的。 当客户端为某个频道发送订阅消息时,它会生成一个新的greenlet。greenlet然后订阅Redis PubSub频道并阻塞,直到收到消息

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)
根据我的理解,如果不产生新的greenlet或取消订阅,就不可能添加订阅

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

更新:我正在构建一个理论上无限的2D地图上的HTML5实时MMO游戏。由于地图的大小,无法将整个地图的状态发送到浏览器。因此,地图被分为分块,玩家拖动地图时动态加载分块(想想谷歌地图)

每当拖动贴图时,客户端/浏览器都会订阅刚刚可见的磁贴的更新,并在短暂延迟后取消订阅不可见磁贴的更新。对订阅的更改应该发生在每个玩家每秒一次,所以频率是相对的

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


然而,我的主要问题是Python Redis PubSub实现阻塞了listen。在上面的示例中,一旦调用red.listen(),在收到消息之前,我无法再更改订阅。上面的示例代码启动了一个新的Greenlet,每个订阅都有一个到Redis的新连接,这可能不是一个好主意。

您没有说明订阅之间的分区原理/要求是什么,即订阅之间的哪些信息流必须与其他订阅分开,所以很难给出确切的答案。我会做一些假设

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

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


我希望这与您所问的有关…

谢谢您的回答!这与我的问题只是部分相关,但你的建议将来可能会很有价值。现在,我不太关心Redis的性能,而是关心Python Redis客户端的正确使用。我试图澄清我的问题。啊,我明白了。我将Redis与C#/booksheeve结合使用(由SO自己的@markgravel,kudos编写),因此我对Python库知之甚少。但我怀疑它的模块化设计暗示了大多数人并没有像你所描述的那样使用它,而当这种情况发生在我身上时,我的蜘蛛感就消失了,也许我应该以不同的方式看待这个问题。在这种情况下,我想知道让每个客户机使用一个非Redis连接到代理/管理服务是否更好,代理/管理服务管理用户的视图/订阅,允许您轻松尝试不同的策略,即使在运行时也是如此。