django / channels

Developer-friendly asynchrony for Django
https://channels.readthedocs.io
BSD 3-Clause "New" or "Revised" License
6.1k stars 800 forks source link

group_send not working...websockets bouncing... #1263

Open pythonBerg opened 5 years ago

pythonBerg commented 5 years ago

Trying to upgrade from django channels v1 that has worked as expected for more than 1 year. Have followed documentation as much as possible...My platform uses channels only as a broadcast tool to update screens with status and content changes.

When using the new syntax for group send, my client never receives the message. Instead, sometime on the server side disconnects the websocket and the restarts with a new handshake.

TTP POST /docReader/postAnnotation/ 200 [0.46, 192.168.56.1:57669] WebSocket DISCONNECT /ws/documents/4/ [192.168.56.1:57682] WebSocket DISCONNECT /ws/annotations/4/ [192.168.56.1:57677]

Some code snippets...

group send action:

serializer = AnnotationSerializer(ann) content = str(JSONRenderer().render(serializer.data),'utf-8')

Group("annotations"+str(self.access_id)).send({'text':content})

    channel_layer = get_channel_layer()
    async_to_sync(channel_layer.group_send)("annotations_"+str(self.access_id),{"type":"annotations.group_send","text": content})

client websocket connect: let weblocation = 'ws://' + window.location.host +'/ws/annotations/'+this.clientDeal.access_id+'/'; this.updateSocket = new WebSocket(weblocation);

consumers: class AnnotationConsumer(WebsocketConsumer): def connect(self):

    self.client_deal = self.scope['url_route']['kwargs']['client_deal']
    self.client_deal_group_name = 'annotations_%s' % self.client_deal
    print(self.client_deal,self.client_deal_group_name)

    # Join room group
    async_to_sync(self.channel_layer.group_add)(self.client_deal_group_name,self.channel_name)
    self.accept()

def disconnect(self, close_code):
    # Leave room group
    async_to_sync(self.channel_layer.group_discard)(self.client_deal_group_name,self.channel_name)

# Receive message from WebSocket
def receive(self, text_data):
    text_data_json = json.loads(text_data)
    message = text_data_json['message']

    # Send message to room group
    async_to_sync(self.channel_layer.group_send)(
        self.client_deal_group_name,
        {
            'type': 'chat_message',
            'message': message
        }
    )

routing: from django.conf.urls import url from docReader import consumers websocket_urlpatterns = [ url(r'^ws/documents/(?P\d+)/$', consumers.DocumentConsumer), url(r'^ws/annotations/(?P\d+)/$', consumers.AnnotationConsumer), url(r'^ws/property/(?P\d+)/$', consumers.PropertyConsumer), url(r'^ws/deals/(?P\d+/$', consumers.DealConsumer), ]

settings: ASGI_APPLICATION = "compscre.routing.application"

CHANNEL_LAYERS = { 'default': { 'BACKEND': 'channels_redis.core.RedisChannelLayer', 'CONFIG': { "hosts": [('127.0.0.1', 6379)], }, }, }

pythonBerg commented 5 years ago

Let's call this closed. Through trial and error I managed to configure the group_send by adding the proper methods in the consumers module. When these were missing, or incorrect in syntax, the websockets were bouncing with no error message posted.

I might suggest some additional clarity in documentation on group_send. In a section entitled "Using Outside Of Consumers", the key elements reside inside the consumer class. This can be particularly confusing for someone comfortable with the less proper channels 1 where group.send() was more singular in its function