Redis
 sql >> Base de données >  >> NoSQL >> Redis

Envoi de messages à des groupes dans Django Channels 2

J'ai trouvé la solution en écrivant cette question et j'ai pensé que quelqu'un d'autre pourrait aussi l'utiliser ! Étant donné que la plupart des questions ici concernent la version des canaux antérieure à 2.0 et supérieure, voici comment vous devez gérer les événements group_send dans vos consommateurs.

Le problème ne résidait pas seulement dans la façon dont j'ai utilisé le group_send Cependant, j'avais supposé à tort que l'ajout de la variable de classe de groupes à mon EventConsumer devrait automatiquement l'ajouter à ce/ces groupes, ce n'est PAS le cas ! Vous devez ajouter des groupes manuellement dans le connect fonction de classe et supprimer des groupes dans le disconnect fonction !

Le problème résidait alors également dans le fait que mon consommateur n'avait pas spécifié de gestionnaires d'événements appropriés. Dans mon fichier de vue, où la demande d'alarme est prise en compte, j'avais défini le 'type' sur 'test'. Le test n'était pas reflété dans ma classe EventConsumer, l'événement n'a donc pas pu être traité. Comme indiqué dans l'exemple multichat ici sur la ligne numéro 146, les fonctions d'assistance sont appelées en fonction du type d'événement envoyé. Ainsi, un type d'événement de 'event.alarm' devrait avoir une fonction correspondante de event_alarm dans votre consommateur ! Simple, mais pas si bien documenté :). Voici à quoi ressemblait la solution finale :

Dans consumers.py , notez le group_add dans connect et le group_discard en déconnexion !

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

Ainsi, la fonction ci-dessus events_alarm est appelé depuis le group_send suivant :

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

S'il vous plaît laissez-moi savoir si vous avez besoin de plus de précisions à la question / réponse! Santé !