Django channels daphne: missing 1 required positional argument: 'send'

Hi I am having issues getting django channels working in production. I am running

gunicorn --bind 0.0.0.0:8000 project_name.asgi

to test that my ASGI setup is working correctly (This all works on my local machine which is super odd. Maybe I am missing something):

This is the error I keep getting :( I have tried everything online but nothing is working:

Traceback (most recent call last):
  File "/home/quilt/quilt_env/lib/python3.10/site-packages/gunicorn/workers/sync.py", line 136, in handle
    self.handle_request(listener, req, client, addr)
  File "/home/quilt/quilt_env/lib/python3.10/site-packages/gunicorn/workers/sync.py", line 179, in handle_request
    respiter = self.wsgi(environ, resp.start_response)
TypeError: ProtocolTypeRouter.__call__() missing 1 required positional argument: 'send'

my requirement file has the following:

channels==4.0.0
channels-redis==4.0.0
daphne==4.0.0
Django==4.1.5
billiard==4.1.0
asgiref==3.6.0

This is my settings file:

ASGI_APPLICATION = 'project_name.asgi.application'

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

This is my asgi.py setup:

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project_name.settings')
django.setup()

from channels.security.websocket import AllowedHostsOriginValidator
from channels.routing import ProtocolTypeRouter, URLRouter
from django_channels_jwt_auth_middleware.auth import JWTAuthMiddlewareStack


import notifications.routing

application = ProtocolTypeRouter({
  'http': get_asgi_application(),
  'websocket': AllowedHostsOriginValidator(
      JWTAuthMiddlewareStack(
          URLRouter(
            notifications.routing.websocket_urlpatterns
          ),
      )
  )
})

This is my routing in notification app:

from django.urls import path
from notifications import consumers

websocket_urlpatterns = [
    path("ws/", consumers.NotificationConsumer.as_asgi()),
]

And then this is my consumer.py file:

import json

from asgiref.sync import sync_to_async
from channels.exceptions import StopConsumer

from channels.generic.websocket import (
    AsyncWebsocketConsumer,
)

from notifications.models import Notifications


class NotificationConsumer(AsyncWebsocketConsumer):
    """
    This consumer is used to send notifications.
    """

    def __init__(self, *args, **kwargs):
        super().__init__(args, kwargs)
        self.group_name = ""
        self.user = None

    @sync_to_async
    def get_all_notifications(self):
        return list(
            Notifications.objects.filter(user=self.user, is_read=False).order_by(
                "-created_date"
            )[0:10]
        )

    async def connect(self):
        self.group_name = "notification"
        self.user = self.scope["user"]
        if not self.user.is_authenticated:
            return
        print("Connected!")

        await self.channel_layer.group_add(self.group_name, self.channel_name)
        await self.accept()

        for notification in await self.get_all_notifications():
            await self.send(
                text_data=json.dumps(
                    {
                        "id": notification.id,
                        "type_value": notification.type_value(),
                        "data": notification.serialized_notification_data_json(),
                    }
                )
            )

    async def disconnect(self, event):
        print("closed connection")
        print("Close code = ", event)
        await self.close()
        raise StopConsumer

    async def receive_json(self, content, **kwargs):
        print(content)
        return super().receive(text_data=json.dumps(content), **kwargs)

    async def notification_send(self, event):
        await self.send(
            text_data=json.dumps({
                "id": event["message"]["id"],
                "type_value": event["message"]["type_value"],
                "data": event["message"]["data"],
            })
        )
Back to Top