Redis
 sql >> Database >  >> NoSQL >> Redis

Invio di messaggi ai gruppi in Django Channels 2

Ho trovato la soluzione mentre scrivevo queste domande e ho pensato che anche qualcun altro potesse farne uso! Poiché la maggior parte delle domande qui fuori riguardano le versioni dei canali precedenti alla 2.0 e successive, questo è il modo in cui dovresti gestire gli eventi group_send nei tuoi consumatori.

Il problema non risiedeva solo nel modo in cui usavo group_send funzione, tuttavia, avevo erroneamente supposto che l'aggiunta della variabile di classe dei gruppi al mio EventConsumer dovesse aggiungerla automaticamente a quel/quei gruppi, NON lo fa! Devi aggiungere i gruppi manualmente in connect class e rimuovi i gruppi in disconnect funzione!

Il problema risiedeva quindi anche nel fatto che il mio consumatore non disponeva di gestori di eventi appropriati specificati. Nel mio file di visualizzazione, in cui viene presa la richiesta di allarme, avevo impostato il "tipo" su "test". Il test non si è riflesso nella mia classe EventConsumer, quindi non è stato possibile elaborare l'evento. Come notato nell'esempio multichat qui alla riga numero 146, le funzioni di supporto vengono chiamate a seconda del tipo di evento inviato. Quindi un tipo di evento di 'event.alarm' dovrebbe avere una funzione corrispondente di event_alarm nel tuo consumatore! Semplice, ma non così ben documentato :). Ecco come si presentava la soluzione finale:

In consumers.py , nota il group_add in Connect e il group_discard in disconnessione!

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']
            }
        )

Quindi, la funzione sopra events_alarm viene chiamato dal seguente 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>')

Per favore fatemi sapere se avete bisogno di ulteriori chiarimenti alla domanda/risposta! Ciao!