Django channels daphne: отсутствует 1 требуемый позиционный аргумент: 'send'

Здравствуйте, у меня проблемы с работой каналов django в продакшене. Я запускаю

gunicorn --bind 0.0.0.0:8000 project_name.asgi

чтобы проверить, что моя настройка ASGI работает правильно (Все это работает на моей локальной машине, что очень странно. Возможно, я что-то упускаю):

Эту ошибку я продолжаю получать :( Я перепробовал все онлайн, но ничего не помогает:

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'

В моем файле требований есть следующее:

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

Вот мой файл настроек:

ASGI_APPLICATION = 'project_name.asgi.application'

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

Вот моя установка asgi.py:

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
          ),
      )
  )
})

Вот моя маршрутизация в приложении уведомлений:

from django.urls import path
from notifications import consumers

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

И вот мой файл consumer.py:

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"],
            })
        )
Вернуться на верх