sql >> Base de Datos >  >> NoSQL >> Redis

Envío de mensajes a grupos en Django Channels 2

¡Encontré la solución mientras escribía estas preguntas y pensé que alguien más también podría usarla! Dado que la mayoría de las preguntas aquí son sobre la versión de canales anterior a la 2.0 y superior, así es como debe manejar los eventos group_send en sus consumidores.

El problema no solo residía en cómo usaba el group_send Sin embargo, asumí erróneamente que agregar la variable de clase de grupos a mi EventConsumer debería agregarla automáticamente a esos grupos, ¡NO es así! Tienes que agregar grupos manualmente en connect función de clase y eliminar grupos en disconnect función!

Entonces, el problema también radicaba en que mi consumidor no tenía especificados los controladores de eventos adecuados. En mi archivo de vista, donde se toma la solicitud de alarma, configuré el 'tipo' en 'prueba'. La prueba no se reflejó en mi clase EventConsumer, por lo que no se pudo procesar el evento. Como se indica en el ejemplo de multichat aquí en la línea número 146, se llama a las funciones auxiliares según el tipo de evento enviado. Entonces, un tipo de evento de 'event.alarm' debería tener una función correspondiente de event_alarm en tu consumidor! Simple, pero no tan bien documentado :). Así es como se veía la solución final:

En consumers.py , tenga en cuenta el group_add en connect y el group_discard en desconexión!

class EventConsumer(JsonWebsocketConsumer):

    def connect(self):
        async_to_sync(self.channel_layer.group_add)(
            'events',
            self.channel_name
        )
        self.accept()

    def disconnect(self, close_code):
        print("Closed websocket with code: ", close_code)
        async_to_sync(self.channel_layer.group_discard)(
            'events',
            self.channel_name
        )
        self.close()

    def receive_json(self, content, **kwargs):
        print("Received event: {}".format(content))
        self.send_json(content)

    # ------------------------------------------------------------------------------------------------------------------
    # Handler definitions! handlers will accept their corresponding message types. A message with type event.alarm
    # has to have a function event_alarm
    # ------------------------------------------------------------------------------------------------------------------

    def events_alarm(self, event):
        self.send_json(
            {
                'type': 'events.alarm',
                'content': event['content']
            }
        )

Entonces, la función anterior events_alarm es llamado desde el siguiente group_send :

from django.shortcuts import HttpResponse

from channels.layers import get_channel_layer

from asgiref.sync import async_to_sync


def alarm(req):
    layer = get_channel_layer()
    async_to_sync(layer.group_send)('events', {
        'type': 'events.alarm',
        'content': 'triggered'
    })
    return HttpResponse('<p>Done</p>')

¡Avíseme si necesita más aclaraciones sobre la pregunta/respuesta! ¡Salud!