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)),
]
Что мне помогло:
- Я установил
daphne
pip install daphne
и добавил его в свойINSTALLED_APPS
в settings.py:
# Application definition
INSTALLED_APPS = [
'daphne',
...,
]
- Я добавил
ASGI_APPLICATION
вsettings.py
и настроилasgi.py
. Вsettings.py
:
ASGI_APPLICATION = 'project.asgi.application'
- В
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]