WebSocket Disconnect: Не найден маршрут для пути 'ws/chat_app/3wVCio/'

Когда я пытаюсь подключиться к рукопожатию с помощью WebSocket, я получаю следующую ошибку в терминале Django:

python3.12/site-packages/channels/routing.py", line 134, in __call__
    raise ValueError("No route found for path %r." % path)
ValueError: No route found for path 'ws/chat_app/3wVCio/'.
WebSocket DISCONNECT /ws/chat_app/3wVCio/ [192.168.0.11:58136]

Я обнаружил, что в предыдущих версиях Django проблема заключалась в том, что вместо path для определения urlpatterns в данном случае следует использовать url(). Однако, url() упразднен и вместо него следует использовать re_path. К сожалению, мне это не помогло

Вот маршрутизация, которую я создал - routing.py

from django.urls import re_path
from .consumers import ChatConsumer

# The WebSocket URL pattern for chat rooms is defined by this code
websocket_urlpatterns = [
    re_path(r'chat_app/(?P<unique_id>\w+)/$', ChatConsumer.as_asgi()),

]

Это WebSocket consumer.py:

import json
from channels.generic.websocket import AsyncWebsocketConsumer
from asgiref.sync import sync_to_async
from .models import Message
from room_app.models import Room

class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):

        self.unique_id = self.scope['url_route']['kwargs']['unique_id']
        self.room_group_name = f'chat_{self.unique_id}'

        # Check if the room exists in the database
        if not await self.room_exists():
            await self.close()
            return

        # Join room group
        self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )

        self.accept()

    def disconnect(self, close_code):
        # Leave room group
        self.channel_layer.group_discard(
            self.room_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']

        # Save message to database
        Message.objects.create(
            room=self.unique_id,
            user=self.scope['user'],
            content=message
        )

        # Send message to room group
        self.channel_layer.group_send(
            self.room_group_name,
            {
                'type': 'chat_message',
                'message': message,
                'username': self.scope['user'].username
            }
        )

    # Receive message from room group
    def chat_message(self, event):
        message = event['message']
        username = event['username']

        # Send message to WebSocket
        self.send(text_data=json.dumps({
            'message': message,
            'username': username
        }))
    
    @sync_to_async
    def room_exists(self):
        return Room.objects.filter(unique_id=self.unique_id).exists()

То, как я настроил свой проект asgi.py

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')

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

Я установил 'daphne' и добавил его в свою settings.py INSTALLED_APPS, где я также определил свою ASGI_APPLICATION и настроил CHANNEL_LAYERS:

ASGI_APPLICATION = 'project.asgi.application'

# Configure channel layers
CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': {
            "hosts": [('192.168.0.11', 6379)],
        },
    },
}

Я также включил websocket_urlpatterns в свой проект urls.py следующим образом:

urlpatterns = [
    path('admin/', admin.site.urls),
    ...,
    path('ws/', include(websocket_urlpatterns)),
]

Что мне помогло:

  1. Я установил daphne pip install daphne и добавил его в свой INSTALLED_APPS в settings.py:
    # Application definition
    INSTALLED_APPS = [
        'daphne',
        ...,
    ]
  1. Я добавил ASGI_APPLICATION в settings.py и настроил asgi.py. В settings.py:
    ASGI_APPLICATION = 'project.asgi.application'
  1. В asgi.py:
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
    
    application = ProtocolTypeRouter({
        "http": get_asgi_application(),
        "websocket": AuthMiddlewareStack(
                URLRouter(
                    websocket_urlpatterns
                ),
            )
        })

Извините, что я не могу объяснить, почему все это сработало. Я просто хотел показать, что сработало у меня.

WebSocket HANDSHAKING /ws/chat_app/FxmZiA/ [192.168.0.11:60081]

WebSocket CONNECT /ws/chat_app/FxmZiA/ [192.168.0.11:60081]

Вернуться на верх