我最近按照官方 Django Channels 文档(版本 4.0.0)在我的 Django 项目中设置了 WebSocket。我已经完成了文档教程并正确配置了我的项目。但是,当我尝试使用 websocketking 测试服务时,我遇到了握手问题。
以下是有关我的配置的一些详细信息:
import os
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.security.websocket import AllowedHostsOriginValidator
from django.core.asgi import get_asgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "schatai.settings")
django_asgi_app = get_asgi_application()
import schatai.routing
application = ProtocolTypeRouter(
{
"http": django_asgi_app,
"websocket": AllowedHostsOriginValidator(
AuthMiddlewareStack(URLRouter(schatai.routing.websocket_urlpatterns))
),
}
)
import json
from asgiref.sync import async_to_sync
from channels.generic.websocket import WebsocketConsumer
class WsTestConsumer(WebsocketConsumer):
def connect(self):
self.accept()
def disconnect(self, close_code):
pass
# Receive message from WebSocket
def receive(self, text_data):
text_data_json = json.loads(text_data)
message = text_data_json["message"]
# Send message to room group
async_to_sync(self.channel_layer.group_send)(
self.room_group_name, {"type": "chat_message", "message": message}
)
# Receive message from room group
def chat_message(self, event):
message = event["message"]
# Send message to WebSocket
self.send(text_data=json.dumps({"message": message}))
from django.urls import re_path, path
from . import consumers
websocket_urlpatterns = [
re_path(r"ws/chat/(?P<room_name>\w+)/$", consumers.SchataiConsumer.as_asgi()),
path(r"ws/", consumers.WsTestConsumer.as_asgi()),
]
当我运行 python manage.py runserver 命令时,服务器在 ASGI 上成功启动。
但是,当我尝试使用 websocketking 测试我的服务时,我收到以下错误消息:
WebSocket HANDSHAKING /ws/ [127.0.0.1:48198]
WebSocket REJECT /ws/ [127.0.0.1:48198]
WebSocket DISCONNECT /ws/ [127.0.0.1:48198]
我想知道是否有人以前遇到过这个问题,或者他们是否对可能导致此握手问题的原因有任何想法。任何帮助或建议将不胜感激。
预先感谢您的协助!
在遇到 Django Channels 的握手问题并进行深入研究后,我已经能够解决这个问题。这是我找到的解决方案:
错误消息“WebSocket HANDSHAKING”后跟“WebSocket REJECT”表示 WebSocket 服务器无法接受连接。这可能是由多种原因造成的,但一个常见的原因是 Django 中允许的来源 (AllowedHosts) 的配置不正确。
要解决此问题,请按照以下步骤操作:
打开 Django 项目的 settings.py 文件。
确保 ALLOWED_HOSTS 变量已正确配置为包含您用于应用程序的 IP 地址或域名。例如:
ALLOWED_HOSTS = ['127.0.0.1', 'localhost', 'websocketking.com']
重新启动 Django 服务器以应用新更改。
没关系。这是帮助我的文档
如果您在握手后仍然遇到 WebSocket 断开连接的问题,即使在尝试了所有其他步骤之后,请确保您的 WebSocketrouting.py 文件也已正确配置。
来自 Django Channels 官方文档的示例。
在早期版本中,例如 Channels 2.x,以下设置就足够了:
...
websocket_urlpatterns = [
re_path(r'ws/chat/(?P<room_name>\w+)/$', consumers.ChatConsumer),
]
但在较新的版本中,缺少 .as_asgi() 将阻止 WebSocket 正确连接。对于较新版本:
...
websocket_urlpatterns = [
re_path(r"ws/chat/(?P<room_name>\w+)/$", consumers.ChatConsumer.as_asgi()),
]
当我尝试升级现有应用程序时,我自己注意到了这一点。干杯!