Redis
 sql >> Base de Dados >  >> NoSQL >> Redis

Enviando mensagens para grupos no Django Channels 2


Encontrei a solução enquanto escrevia essas perguntas e pensei que outra pessoa também poderia usá-la! Como a maioria das perguntas aqui são sobre a versão de canais anterior à 2.0 e superior, é assim que você deve lidar com eventos group_send em seus consumidores.

O problema não estava apenas em como eu usei o group_send No entanto, eu havia assumido erroneamente que adicionar a variável de classe groups ao meu EventConsumer deveria adicioná-la automaticamente a esse/aqueles grupos, NÃO! Você precisa adicionar grupos manualmente no connect função de classe e remover grupos no disconnect função!

O problema também estava no fato de que meu consumidor não tinha manipuladores de eventos adequados especificados. No meu arquivo de visualização, onde a solicitação de alarme é recebida, eu configurei o 'tipo' para 'teste'. O teste não foi refletido na minha classe EventConsumer, portanto, o evento não pôde ser processado. Conforme observado no exemplo de multichat aqui na linha número 146, as funções auxiliares são chamadas dependendo do tipo de evento enviado. Portanto, um tipo de evento 'event.alarm' deve ter uma função correspondente de event_alarm no seu consumidor! Simples, mas não tão bem documentado :). Veja como ficou a solução final:

Em consumers.py , observe o group_add em connect e o group_discard em desconexão!
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']
            }
        )

Então, a função acima events_alarm é chamado do seguinte 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>')

Por favor, deixe-me saber se você precisar de mais esclarecimentos para a pergunta/resposta! Saúde!