Adnan Roy
Adnan Roy

Reputation: 26

Django Channels: Mission Positional Arguments send and receive

currently im developing a live chat system using django channels, but im facing below mentioned issue. please tell me how i can solve below mentioned issue.

channels==4.0.0

Here my Consumer.py `

import json
from channels.generic.websocket import AsyncWebsocketConsumer


class ChatConsumer(AsyncWebsocketConsumer):
    def __init__(self, *args, **kwargs):
        super().__init__(args, kwargs)
        self.booking_id = None
        self.booking_group_name = None

    async def connect(self):
        self.booking_id = 2
        self.booking_group_name = 'chat_%s' % self.booking_id

        # Join booking group
        await self.channel_layer.group_add(
            self.booking_group_name,
            self.channel_name
        )
        await self.accept()

    async def disconnect(self, close_code):
        # Leave booking group
        await self.channel_layer.group_discard(
            self.booking_group_name,
            self.channel_name
        )

    # Receive message from WebSocket

    async def receive(self, text_data=None, bytes_data=None):
        text_data_json = json.loads(text_data)
        sender = self.scope['user']
        message = text_data_json['message']

        # Save chat message to database
        await self.save_chat_message(sender, message)

        # Send message to booking group
        await self.channel_layer.group_send(
            self.booking_group_name,
            {
                'type': 'chat_message',
                'sender': sender.username,
                'message': message
            }
        )

    async def chat_message(self, event):
        sender = event['sender']
        message = event['message']

        # Send message to WebSocket
        await self.send(text_data=json.dumps({
            'sender': sender,
            'message': message
        }))

    def save_chat_message(self, sender, message):
        from booking.models import Booking, CustomerSupportCollection, CustomerSupportChat
        booking = Booking.objects.get(id=self.booking_id)
        collection = CustomerSupportCollection.objects.get_or_create(
            booking=booking,
        )
        chat_message = CustomerSupportChat.objects.create(
            booking=booking,
            collection=collection,
            user=sender,
            message=message
        )
        return chat_message
`

asgi.py

"""
ASGI config for cleany project.

It exposes the ASGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/
"""

import os
import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from .routing import websocket_urlpatterns

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cleany.settings")

django_asgi_app = get_asgi_application()


application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    "websocket": AuthMiddlewareStack(
        URLRouter(
            websocket_urlpatterns
        )
    )
})

routing.py


from django.urls import re_path, path
from django_private_chat2 import consumers

from cleany.consumer import ChatConsumer

websocket_urlpatterns = [
    re_path(r'ws/chat/$', ChatConsumer.as_asgi()),
]

But it show this error:

enter image description here

actually i tried django channels for live chat but im facing this error.

Upvotes: 1

Views: 747

Answers (1)

Razenstein
Razenstein

Reputation: 3717

Error Explanation:

Just to try to explain were this error message comes from: this looks like you are running the app with runserver via wsgi instead of asgi. Also it seems you make an ordinary http request to http://localhost:8000/ws/chat instead of ws://localhost:8000/ws/chat . Finally I suppose you have a urlpattern in urls.py like below that catches the http request and causes the error as via wsgi the attributes send and receive are not needed (wsgi class bassed views have an as_wsgi() method) .

urlpatterns = [
    re_path(r'ws/chat/$', ChatConsumer.as_asgi()),   # as_asgi() must not be used in urlpattners for wsgi
]

maybe that is left from a phase were you started to work with ChatConsumer and did not yet have the full picture how to use asgi.

At least asgi.py is not involved in the whole thing right now.

Proposal for solution:

You need to do the following things: (https://channels.readthedocs.io/en/stable/installation.html)

  1. install channels and daphne (async server)
pip uninstall channels
python -m pip install -U channels["daphne"]
  1. in settings.py add daphne (only) to installed apps:
INSTALLED_APPS = (
    "daphne",
    ...
  1. in settings.py add ASGI_APPLICATION:
WSGI_APPLICATION = "xxxx.wsgi.application"
ASGI_APPLICATION = "xxxx.asgi.application"
  1. in asg.py
application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    "websocket": AuthMiddlewareStack(
        URLRouter(
            websocket_urlpatterns
        )
    )
})
  1. now call `python manage.py runserver' and this will automatically start daphne/asgi and you can connect with ws

... of course you can use other asgi servers then daphne

Upvotes: 1

Related Questions