使用daphne部署django channles websocket 项目

发布时间:2021-03-29 10:35:17编辑:admin阅读(3244)

    一、概述

    在上一篇文章中,链接如下:https://www.cnblogs.com/xiao987334176/p/14361893.html

    开发了一个django channles websocket 项目,用的是asgi。官方推荐使用asgi服务器daphne,来处理websocket请求

    daphne

    Daphne 是一个纯Python编写的应用于UNIX环境的由Django项目维护的ASGI服务器。它扮演着ASGI参考服务器的角色。

     

    安装 Daphne

    你可以通过 pip 来安装 Daphne

    python -m pip install daphne

     

    在 Daphne 中运行 Django

    一旦 Daphne 安装完毕,你就可以使用 daphne 命令了,它将用来启动 Daphne 服务进程。在最简单的情形下,Daphne 加上包含一个 ASGI 应用模块的位置和应用的名称(以冒号分隔)。

    对于一个典型的 Django 项目,可以像下面这样来启动 Daphne

    daphne myproject.asgi:application

    它将开启一个进程,监听 127.0.0.1:8000。这需要你的项目位于 Python path 上。为了确保这点,你应该在与 manage.py 文件相同的路径中运行这个命令。

     

    如果需要更改运行端口,使用以下命令:

    daphne myproject.asgi:application -b 0.0.0.0 -p 8000

    说明:

    -b 监听地址

    -p 监控端口

     

    二、实际项目运行

    在上一篇文章中,链接如下:https://www.cnblogs.com/xiao987334176/p/14361893.html

    已经开发好了,但是直接使用daphne运行,会遇到以下错误:

    比如1:

    django.core.exceptions.ImproperlyConfigured: Requested setting LOGGING_CONFIG, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.

    比如2:

    django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.

     

    解决方法

    修改asgi.py,增加django.setup()

    import os
    import django
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'websocket_demo.settings')
    django.setup()
    
    from channels.auth import AuthMiddlewareStack
    from django.core.asgi import get_asgi_application
    # Import other Channels classes and consumers here.
    from channels.routing import ProtocolTypeRouter, URLRouter
    # from apps.websocket_app.urls import websocket_urlpatterns
    from websocket_demo.urls import websocket_urlpatterns
    
    # application = get_asgi_application()
    application = ProtocolTypeRouter({
        # Explicitly set 'http' key using Django's ASGI application.
        "http": get_asgi_application(),
        'websocket': AuthMiddlewareStack(
            URLRouter(
                websocket_urlpatterns
            )
        ),
    })

    注意:django.setup()要置顶,不能在底部,否则使用daphne启动会报上面的错误。

     

    运行项目

    注意:要在manage.py同级目录下执行此命令

    daphne websocket_demo.asgi:application -b 0.0.0.0 -p 8000

     

    三、nginx+daphne+supervise

    官方文档:https://channels.readthedocs.io/en/stable/deploying.html#configuring-the-asgi-application

    根据官方文档,推荐使用nginx+daphne+supervise

     

    环境说明

    操作系统:centos 7.5

    ip地址:192.168.31.165

     

    supervise

    yum install -y supervisor

     

    生成配置文件

    echo_supervisord_conf > /etc/supervisord.conf

     

    修改配置文件/etc/supervisord.conf,最后一行增加

    [include]
    files = supervisord.d/*.ini

    表示配置文件读取supervisord.d目录下所有后缀为.ini的文件。

     

    创建配置目录,并创建配置文件

    mkdir /etc/supervisord.d/vi /etc/supervisord.d/asgi.ini

    内容如下:

    [fcgi-program:asgi]
    # TCP socket used by Nginx backend upstream
    socket=tcp://localhost:8000
    
    # Directory where your site's project files are located
    directory=/tmp/internal_tools
    
    # Each process needs to have a separate socket file, so we use process_num
    # Make sure to update "mysite.asgi" to match your project name
    command=/virtualenvs/venv1/bin/daphne -u /run/daphne/daphne%(process_num)d.sock --fd 0 --access-log - --proxy-headers internal_tools.asgi:application
    
    # Number of processes to startup, roughly the number of CPUs you have
    numprocs=4
    
    # Give each process a unique name so they can be told apart
    process_name=asgi%(process_num)d
    
    # Automatically start and recover processes
    autostart=true
    autorestart=true
    
    # Choose where you want your log to go
    stdout_logfile=/var/log/asgi.log
    redirect_stderr=true

    注意:红色部分,请根据实际情况修改。

     

    启动supervisord

    supervisord -c /etc/supervisord.conf

     

    查看asgi运行状态

    # supervisorctl 
    asgi:asgi0                       RUNNING   pid 17567, uptime 0:00:04
    asgi:asgi1                       RUNNING   pid 17566, uptime 0:00:04
    asgi:asgi2                       RUNNING   pid 17569, uptime 0:00:04
    asgi:asgi3                       RUNNING   pid 17568, uptime 0:00:04

    可以看到,有4个进程。如果状态不是RUNNING,请查看ini配置文件,是否正常。

     

    nginx

    nginx安装就很简单了,一条命令解决

    yum install -y nginx

     

    修改虚拟配置文件/etc/nginx/conf.d/asgi.conf

    upstream channels-backend {
        server localhost:8000;
    }
    server {
        listen 8093;    
        location / {
            try_files $uri @proxy_to_app;
        }
        location @proxy_to_app {
            proxy_pass http://channels-backend;
    
            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;
        }
    }

    注意红色部分,upstream 是asgi的监听端口。在server里面的8093是对外端口,也可以改成别的,根据实际情况而定。

     

    最后加载nginx配置文件

    nginx -s reload

     

    扩展

    如果是前后端分离架构,在vue代码中,配置nginx的服务器地址即可,比如:

    Vue.prototype.$apihost = " 
    Vue.prototype.$websockethost = "ws://192.168.31.165:8093"

    注意:daphne不光可以处理asgi,它也可以处理wsgi,没有必要部署uswgi来处理wsgi了。

     

    总之:nginx+daphne+supervise就可以处理django的所有功能了。

     

     

    本文参考链接:

    https://stackoverflow.com/questions/53683806/django-apps-arent-loaded-yet-when-using-asgi

    https://docs.djangoproject.com/zh-hans/3.1/howto/deployment/asgi/daphne/

     

    https://blog.csdn.net/qq_41854273/article/details/89332836

    https://www.cnblogs.com/chenjw-note/p/12516097.html


关键字