websockets socket real example application python django websocket socket.io gevent-socketio

python - real - Cómo emitir un evento SocketIO en el servidor



socket django example (2)

Estoy ejecutando una aplicación Django gevent-socketio.

Tengo algo similar a esta clase

@namespace(''/connect'') class ConnectNamespace(BaseNamespace): def on_send(self, data): # ...

Sin embargo, si recibo los eventos del cliente javascript, todo funciona y, por ejemplo, el evento de send se procesa correctamente

Estoy un poco perdido si quiero emit algún evento en el lado del servidor. Puedo hacerlo dentro de la clase con socket.send_packet

Pero ahora quiero vincular algún evento a la señal de post_save , por lo que me gustaría send_packet desde fuera de esta clase de espacio de nombres, una forma de hacerlo sería

ConnectNamespaceInstance.on_third_event(''someeventname'')

Simplemente no puedo entender cómo puedo obtener la instancia de ConnectNamespaceInstance

Para resumir, solo quiero enviar un evento a un cliente javascript después de recibir la señal post_save


Aparte de la respuesta de Femi, que creo que ciertamente funciona. El uso de Redis probablemente le daría un poco más de flexibilidad y el uso de greenlet de gevent puede calificar este enfoque como un poco más "en el marco", ya que ya está utilizando 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))

Y en tu post_save, puedes hacerlo.

red = redis.StrictRedis(REDIS_HOST) red.publish(channel_label, message_data)


Lo que probablemente querrá hacer es agregar una variable de módulo para rastrear conexiones, digamos _connections , así:

_connections = {} @namespace(''/connect'') class ConnectNamespace(BaseNamespace):

y luego agregue los métodos de initialize y disconnect que usan algún identificador feliz al que puede hacer referencia más adelante:

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)

Cuando necesite generar un evento, puede buscar la conexión correcta en la variable _connections y disparar el evento con emit .

(No probé nada de esto, pero he usado un patrón similar en muchos otros idiomas: no veo ninguna razón por la que esto tampoco funcionaría en Python).