Sending messages to groups in Django Channels 2

前端 未结 3 854
离开以前
离开以前 2020-12-24 09:24

I am completely stuck in that I cannot get group messaging to work with Channels 2! I have followed all tutorials and docs that I could find, but alas I haven\'t found what

3条回答
  •  萌比男神i
    2020-12-24 09:48

    I found the solution while writing this questions and thought that someone else might also make use of it! Since most of the questions out here are about channels version prior to 2.0 and above, this is how you should handle group_send events in your consumers.

    The problem did not only lie in how I used the group_send function though, I had wrongly assumed that adding the groups class variable to my EventConsumer should automatically add it to that/those groups, it does NOT! You have to add groups manually in the connect class function and remove groups in the disconnect function!

    The problem then also lied in that my consumer did not have proper event handlers specified. In my view file, where the alarm request is taken in, I had set the 'type' to 'test'. Test was not reflected in my EventConsumer class so the event could not be processed. As noted in the multichat example here on line number 146, the helper functions get called depending on the type of the event sent. So an event type of 'event.alarm' should have a corresponding function of event_alarm in your consumer! Simple, but not so well documented :). Here is what the final solution looked like:

    In consumers.py, note the group_add in connect and the group_discard in disconnect!

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

    So, the above function events_alarm gets called from the following 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('

    Done

    ')

    Please let me know if you need any more clarifications to the question/answer! Cheers!

提交回复
热议问题