Подтвердить что ты не робот

Как испустить событие SocketIO на сервере

Я запускаю приложение gangent-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

Чтобы подвести итог, я просто хочу отправить событие клиенту javascript после получения сигнала post_save

4b9b3361

Ответ 1

Что вы, вероятно, хотите сделать, это добавить переменную модуля для отслеживания соединений, например _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).

Ответ 2

Другой, тогда ответ Femi, который, я думаю, безусловно работает. Использование Redis, вероятно, даст вам немного большую гибкость, и использование greenlet от gevent может квалифицировать этот подход как немного более "в рамках", поскольку вы уже используете 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)