带有 Django 通道的 Websocket 不起作用,连接失败



你好,很棒的人!

我创建了一个聊天室,django-channels.每次我尝试在生产环境中通过 Web 套接字连接到我的聊天室时,都会失败。 在本地,它可以正常工作。

我在数字海洋上托管

点冻结:

channels==2.1.2
channels-redis==2.3.0
daphne==2.2.1
'''

我已经安装了redis-server

sudo apt-get install redis-server

这是我的设置。

INSTALLED_APPS = [
# '''
'channels',
# '''
] 
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [os.environ.get('REDIS_URL', 'redis://localhost:6379')],
},
},
}
ASGI_APPLICATION = "project_name.routing.application"

这是我和wsgi.py一起asgi.py

import os
import django
from channels.routing import get_default_application
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project_name.settings")
django.setup()
application = get_default_application()

这是我的project_folder.rounting.py

application = ProtocolTypeRouter({
'websocket':AllowedHostsOriginValidator(
AuthMiddlewareStack(
URLRouter([
# my urls
])
)
)
})

我一直在 Firefox 和其他浏览器中得到类似的东西:

Firefox 无法在 wss://www.domain_name.com/url-to/1/XBvZjr2pqdf6fhy/建立与服务器的连接

但是它在本地工作。

更新

这是我的 js

var loc = window.location;
var wsStart = loc.protocol == "https:" ? "wss://" : "ws://"
var endpoint = wsStart + loc.host + loc.pathname
var socket = new ReconnectingWebSocket(endpoint);
socket.onmessage = function(e){
// code
}

我终于解决了这个问题,并在与wss://的连接下sslws使用。

对于那些面临相同问题的人。

请注意,我使用

  • http请求gunicorn作为 Web 服务器
  • daphne作为wsWeb 套接字的 Web 服务器
  • nginx为反向代理

asgi.py

import os
import django
from channels.routing import get_default_application
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings")
django.setup()
application = get_default_application()

settings.py

ASGI_APPLICATION = "project.routing.application"
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [(os.environ.get('REDIS_HOST', 'localhost'),6379)],
},
},
}

使用 django 设置asgi后,我使用supervisorctl来保持daphne运行。在/etc/supervior/conf.d/中创建文件daphne_asgi.conf

daphne_asgi.conf

[program:asgi_daphne]
directory=/path/to/your/project
command=/executable/path/to/daphne --bind 0.0.0.0 --port 8010 project.asgi:application
# 0.0.0.0 ip of your website
# I choose the port 8010 for daphne
stdout_logfile=/path/to/log/daphne.log
autostart=true
autorestart=true
redirect_stderr=true

运行以下命令以更新启动守护程序

sudo supervisorctl reread
sudo supervisorctl update

这是nginx的配置

map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream websocket {
server 0.0.0.0:8010;
}

达芙妮中使用的主机和端口...--bind 0.0.0.0 --port 8010

#redirection to a https
server {
listen 80;
server_name 0.0.0.0 example.com www.example.com;
client_max_body_size 10M;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl default_server;
server_name www.example.com;
client_max_body_size 10M;
# ssl configuration
...
# normal http request, I use .sock
location / {
include proxy_params;
proxy_pass http://unix:/path/to/project.sock;
}
# ws request /ws/
location /ws/ {
proxy_pass http://websocket;
# this magic is needed for WebSocket
proxy_http_version  1.1;
proxy_set_header    Upgrade $http_upgrade;
proxy_set_header    Connection $connection_upgrade;
proxy_set_header    Host $http_host;
proxy_set_header    X-Real-IP $remote_addr;
}
}

请注意,我在 ws 网址中添加了/ws/

application = ProtocolTypeRouter({
'websocket':AllowedHostsOriginValidator(
AuthMiddlewareStack(
URLRouter(
[
url(r'^ws/$', HelloConsumer),
]
)
)
)
})

最重要的是,使用 redis 5.0.9。否则将再次出现错误。

从 github.com/tporadowski/redis/releases 获取

最新更新