我目前正在尝试安装Django Channels聊天应用程序,并且我已经尽我所知遵循了文档-显然,当事情不顺利时,总会有一个解决方案,但我只是很难找出我在让它工作时出了什么问题
到目前为止,我已经安装了Django频道,在settings.py中正确配置了我的channel_层,我已经通过创建我的consumer.py文件、utils.py、views.py和chat.html模板文件引用了文档和其他在线教程
我还配置了nginx、gunicorn、daphne和redis,我可以确认所有这些服务都在运行。我已经安装了LetsEncrypt并允许使用SSL端口(443用于https连接)
我目前正在现场制作服务器上访问Django网站,如下所示:https://mydomain:8001 我的聊天室的直接链接配置为https://mydomain:8001/messenger
(我已允许端口8001通过防火墙)
以下是我从聊天页面收到的状态消息:
SUCCESS {response: "Successfully got the chat.", chatroom_id: 1}chatroom_id: 1response: "Successfully got the chat."__proto__: Object
(index):303 setupWebSocket: 1
(index):371 ChatSocket connecting..
WebSocket connection to 'wss://www.<mydomain>.com:8001/messenger/1/' failed:
setupWebSocket @ (index):317
success @ (index):389
c @ jquery.min.js
fireWith @ jquery.min.js
l @ jquery.min.js
(anonymous) @ jquery.min.js
ChatSocket error Event {isTrusted: true, type: "error", target: WebSocket, currentTarget: WebSocket, eventPhase: 2, …}bubbles: falsecancelBubble: falsecancelable: falsecomposed: falsecurrentTarget: WebSocket {url: "wss://<mydomain>:8001/messenger/1/", readyState: 3, bufferedAmount: 0, onopen: null, onOpen: ƒ, …}defaultPrevented: falseeventPhase: 0isTrusted: truepath: []returnValue: truesrcElement: WebSocket {url: "wss://<mydomain>:8001/messenger/1/", readyState: 3, bufferedAmount: 0, onopen: null, onOpen: ƒ, …}target: WebSocket {url: "wss://<mydomain>:8001/messenger/1/", readyState: 3, bufferedAmount: 0, onopen: null, onOpen: ƒ, …}timeStamp: 43973.62500001327type: "error"__proto__: Event
(index):357 Chat socket closed.
如果您能帮助解决此问题,我们将不胜感激。如果您能建议您应该查看哪些文件,我将很高兴地用我的聊天应用程序所需文件的内容更新我的问题。:-)
谢谢大家!
文件内容:
nginx.conf
server {
listen 80;
server_name myapp mydomain.com www.mydomain.com;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/myapp;
}
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://unix:/home/myapp/myapp.sock;
}
location /ws/ {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
proxy_pass https://127.0.0.1:8001;
}
location /wss/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:8001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
routing.py
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.security.websocket import AllowedHostsOriginValidator
from django.urls import path, re_path
from messenger.consumers import ChatConsumer
application = ProtocolTypeRouter({
'websocket': AllowedHostsOriginValidator(
AuthMiddlewareStack(
URLRouter([
path('messenger/<room_id>/', ChatConsumer),
])
)
),
})
设置.py
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [('127.0.0.1', 6379)],
},
},
}
我在控制台中收到错误:(index):317 WebSocket connection to 'wss://www.mydomain.com:8001/messenger/1/' failed:
(上面写着mydomain.com,我的实际域是在那里输入的:)
来自journalctl
Jun 21 14:22:56 myhostname.com python3[36088]: 2021-06-21 14:22:56,576 INFO Starting server at ssl:8001:privateKey=/etc/letsencrypt/live/mydomain.com/privkey.pem:certKey=/etc/let>
Jun 21 14:22:56 myhostname.com python3[36088]: 2021-06-21 14:22:56,576 INFO HTTP/2 support not enabled (install the http2 and tls Twisted extras)
Jun 21 14:22:56 myhostname.com python3[36088]: 2021-06-21 14:22:56,577 INFO Configuring endpoint ssl:8001:privateKey=/etc/letsencrypt/live/mydomain.com/privkey.pem:certKey=/etc/l>
Jun 21 14:22:56 myhostname.com python3[36088]: 2021-06-21 14:22:56,584 INFO Listening on TCP address 0.0.0.0:8001
Daphne日志中的错误
Jun 21 14:38:51 myhostname.com python3[36088]: Traceback (most myhostname.com python3[36088]: File "/usr/local/lib/python3.6/site-packages/channels/routing.py", line 71, in __call__
Jun 21 14:38:51 myhostname.com python3[36088]: return await application(scope, receive, send)
Jun 21 14:38:51 myhostname.com python3[36088]: File "/usr/local/lib/python3.6/site-packages/channels/security/websocket.py", line 37, in __call__
Jun 21 14:38:51 myhostname.com python3[36088]: return await self.application(scope, send, receive)
Jun 21 14:38:51 myhostname.com python3[36088]: File "/usr/local/lib/python3.6/site-packages/channels/sessions.py", line 47, in __call__
Jun 21 14:38:51 myhostname.com python3[36088]: return await self.inner(dict(scope, cookies=cookies), receive, send)
Jun 21 14:38:51 myhostname.com python3[36088]: File "/usr/local/lib/python3.6/site-packages/channels/sessions.py", line 254, in __call__
Jun 21 14:38:51 myhostname.com python3[36088]: return await self.inner(wrapper.scope, receive, wrapper.send)
Jun 21 14:38:51 myhostname.com python3[36088]: File "/usr/local/lib/python3.6/site-packages/channels/auth.py", line 181, in __call__
Jun 21 14:38:51 myhostname.com python3[36088]: return await super().__call__(scope, receive, send)
Jun 21 14:38:51 myhostname.com python3[36088]: File "/usr/local/lib/python3.6/site-packages/channels/middleware.py", line 26, in __call__
Jun 21 14:38:51 myhostname.com python3[36088]: return await self.inner(scope, receive, send)
Jun 21 14:38:51 myhostname.com python3[36088]: File "/usr/local/lib/python3.6/site-packages/channels/routing.py", line 160, in __call__
Jun 21 14:38:51 myhostname.com python3[36088]: send,
Jun 21 14:38:51 myhostname.com python3[36088]: File "/usr/local/lib/python3.6/site-packages/asgiref/compatibility.py", line 33, in new_application
Jun 21 14:38:51 myhostname.com python3[36088]: instance = application(scope)
Jun 21 14:38:51 myhostname.com python3[36088]: File "/usr/local/lib/python3.6/site-packages/channels/generic/websocket.py", line 159, in __init__
Jun 21 14:38:51 myhostname.com python3[36088]: super().__init__(*args, **kwargs)
Jun 21 14:38:51 myhostname.com python3[36088]: TypeError: object.__init__() takes no parameters
我认为问题在于配置。在nginx中,您必须指定URL前缀,而不是协议,也不需要同时添加
ws
和wss
。nginx配置必须与此类似因此,要通过Websocket协议进行连接,您必须访问
wss://www.<mydomain>.com:8001/ws/
下的内容。为此,asgi路由还必须包含ws
前缀。此外,您应该在使用者上使用as_asgi()
。(https://channels.readthedocs.io/en/stable/topics/routing.html)现在您应该能够连接到
wss://www.<mydomain>.com:8001/ws/messenger/1/
(不要忘记ws!)终于让Django频道工作了(终于让我的Websocket连接工作了)——非常感谢Alexandr的帮助
从日志中,我发现以下错误:
ERROR: TypeError: object.__init__() takes exactly one argument (the instance to initialize)
我忘了在我呼叫聊天室消费者的地方加上
as_asgi()
。因此,我将路由路径从:path('ws/messenger/<room_id>/', ChatConsumer),
到
path('ws/messenger/<room_id>/', ChatConsumer.as_asgi()),
我的Websocket现在已打开并已成功连接!快乐的日子
再次非常感谢你的帮助Alexandr
相关问题 更多 >
编程相关推荐