目前我正在使用 django 频道开发实时聊天系统,但我面临以下提到的问题。请告诉我如何解决下面提到的问题。
频道==4.0.0
这是我的 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
)
)
})
路由.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()),
]
但是它显示这个错误:
实际上我尝试了 django 频道进行实时聊天,但我遇到了这个错误。
错误解释:
只是试图解释此错误消息是否来自:这看起来您正在通过 wsgi 而不是 asgi 使用 runserver 运行应用程序。此外,您似乎向 http://localhost:8000/ws/chat 而不是 ws://localhost:8000/ws/chat 发出了普通的 http 请求。最后我想你在 urls.py 中有一个 urlpattern 如下所示,它捕获 http 请求并导致错误,因为通过 wsgi 不需要属性发送和接收(wsgi 类 bassed 视图有一个 as_wsgi() 方法)。
urlpatterns = [
re_path(r'ws/chat/$', ChatConsumer.as_asgi()), # as_asgi() must not be used in urlpattners for wsgi
]
如果您开始使用 ChatConsumer 并且还没有了解如何使用 asgi 的全貌,那可能是某个阶段遗留下来的。
至少 asgi.py 现在没有参与整个事情。
解决方案:
你需要做以下事情: (https://channels.readthedocs.io/en/stable/installation.html)
pip uninstall channels
python -m pip install -U channels["daphne"]
INSTALLED_APPS = (
"daphne",
...
WSGI_APPLICATION = "xxxx.wsgi.application"
ASGI_APPLICATION = "xxxx.asgi.application"
application = ProtocolTypeRouter({
"http": get_asgi_application(),
"websocket": AuthMiddlewareStack(
URLRouter(
websocket_urlpatterns
)
)
})
...当然你可以使用其他 asgi 服务器然后 daphne