我正在运行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客户端发送一个事件
答案 0 :(得分:7)
你可能想要做的是添加一个模块变量来跟踪连接,比如说_connections
,如下所示:
_connections = {}
@namespace('/connect')
class ConnectNamespace(BaseNamespace):
然后添加initialize
和disconnect
方法,这些方法使用您稍后可以参考的一些快乐标识符:
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中也不起作用的原因。)
答案 1 :(得分:0)
除了Femi的答案,我认为肯定有效。使用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)