Django 通道 websocket 连接和断开连接(Nginx + Daphne + Django + Channels)

Posted

技术标签:

【中文标题】Django 通道 websocket 连接和断开连接(Nginx + Daphne + Django + Channels)【英文标题】:Django channels websocket connecting and disconnecting (Nginx + Daphne + Django + Channels) 【发布时间】:2021-03-07 15:03:11 【问题描述】:

我在使用 nginx + Gunicorn + Daphne + Django 的生产虚拟机中部署它时遇到问题。 我一直在本地虚拟机中对其进行测试,它可以正常工作,但是在生产中,套接字正在连接和断开连接。 我附加了我的 nginx 配置、asgi.py 和 routing.py。 我使用命令````$ daphne -p 8010 project.asgi:application``` enter image description here

# Nginx config
upstream test_project 
        server localhost:8001;

upstream test_project_websocket 
        server localhost:8002;

server 
        listen 1881;

        location / 
                proxy_pass http://test_project;
        
        location /ws/ 
                proxy_pass http://test_project_websocket;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "Upgrade";
                proxy_redirect off;
        

        proxy_set_header Host $host;


#asgi.py
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'WebServer.settings')
django.setup()

from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter
import Andon.routing # app.routing
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.layers import get_channel_layer


application = ProtocolTypeRouter(
    "http": get_asgi_application(),
    "websocket": AuthMiddlewareStack(
            URLRouter(
                    Andon.routing.websocket_urlpatterns,
            ),
        ),
)
# routing.py
from django.urls import path, re_path
from . import consumers

from channels.layers import get_channel_layer

websocket_urlpatterns = [
    re_path(r'ws/andon/$', consumers.AndonConsumer.as_asgi()),
]

编辑 27-11-20: 还没有解决,但发现了一些有趣的东西。 如果您使用的是旧版本的 redis,请确保您有这个版本:

channels==3.0.2
channels-redis==2.4.1

编辑 27-11-20:部分解决 我认为我的 nginx 配置有一些问题,因为如果我尝试直接连接到 daphne 端口,它工作得很好,但如果我从 nginx 重定向流量,它不会

编辑 16-12-20:解决方案 我有一个旧版本的 nginx 1.10,我将它升级到 1.16 并且没有任何问题,使用这篇文章的配置:Config

【问题讨论】:

【参考方案1】:

这是您正在寻找的配置

# Connecting to daphne socket
upstream test_project_websocket 
        server localhost:8010;

....
    # Notice the "/" at then end of location & proxy_pass url
    location /ws/ 
        proxy_pass http://test_project_websocket/;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        proxy_redirect off;
        proxy_set_header Host $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-Host $server_name;
    

    location / 
         proxy_pass http://test_project;
    

【讨论】:

我注意到在原始帖子中我写错了端口,但在部署中我写得很好。我尝试了你的答案,没有用,我检查了你指出的“/”,还尝试从 asgi 路由中删除 originvalidators,但它没有用。我会继续搜索信息 您的 nginx 1881 端口是否使用 ssl 运行?您可以输入客户端代码以及您如何尝试连接服务器吗?还有一个 daphne 控制台屏幕以及它在连接时引发的任何警告都可以很好地调试问题。 我已经尝试了一切,但没有任何效果,直到我看到这个配置。我注意到你把 /ws/config 放在 /config 上面。我测试了这个,瞧!经过 1 周的奋斗,现在一切正常:)

以上是关于Django 通道 websocket 连接和断开连接(Nginx + Daphne + Django + Channels)的主要内容,如果未能解决你的问题,请参考以下文章

通道 Websocket 立即与 ssl 断开连接

Django Channels Websockets 立即连接和断开连接

握手后 Websocket 立即断开连接(鳄梨酱)

如何使用 Django 通道为 Django Rest Api 打开 Websocket?

websocket基本概念

websocket