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).