20

我正在运行一个 gevent-socketio Django 应用程序。

我有类似这堂课的东西

@namespace('/connect')
class ConnectNamespace(BaseNamespace):

    def on_send(self, data):
        # ...

但是,如果我从 javascript 客户端收到事件,一切正常,例如send事件被正确处理

emit如果我想在服务器端进行一些活动,我会有点迷茫。我可以在课堂上做到这一点socket.send_packet

但是现在我想将一些事件链接到post_save信号,所以我想send_packet从这个命名空间类之外,这样做的一种方法是

ConnectNamespaceInstance.on_third_event('someeventname')

我只是不知道如何获得 ConnectNamespaceInstance 的实例

总结一下,我只想在收到post_save信号后向javascript客户端发送一个事件

4

2 回答 2

7

您可能想要做的是添加一个模块变量来跟踪连接,_connections例如:

_connections = {}

@namespace('/connect')
class ConnectNamespace(BaseNamespace):

然后添加initializedisconnect使用一些你可以稍后引用的快乐标识符的方法:

def initialize(self, *args, **kwargs):
    _connections[id(self)] = self
    super(ConnectNamespace, self).initialize(*args, **kwargs)

def disconnect(self, *args, **kwargs):
    del _connections[id(self)]
    super(ConnectNamespace, self).disconnect(*args, **kwargs)

_connections当您需要生成事件时,您只需在变量中查找正确的连接,然后使用emit.

(没有对此进行任何测试,但我在许多其他语言中使用了类似的模式:看不出有任何理由说明这在 Python 中也不起作用)。

于 2013-05-29T17:25:21.283 回答
0

除了费米的回答,我认为这肯定有效。使用 Redis 可能会给您更多的灵活性,并且使用 gevent 中的 greenlet 可能会使这种方法更加“在框架中”,因为您已经在使用 gevent-socketio :D

REDIS_HOST = getattr(settings, 'REDIS_HOST', '127.0.0.1')


class YourNamespace(BaseNamespace):

    def _listener(self, channel_label_you_later_call_in_post_save):
        pubsub = redis.StrictRedis(REDIS_HOST).pubsub()
        pubsub.subscribe(chan)
        while True:
            for i in pubsub.listen():
                self.send({'message_data': i}, json=True) 

    def recv_message(self, message):
        if is_message_to_subscribe(message):
            self.spawn(self.listener, get_your_channel_label(message))

在你的 post_save 中,你可以做

red = redis.StrictRedis(REDIS_HOST)
red.publish(channel_label, message_data)
于 2015-01-09T11:22:08.950 回答