Django支持WebSocket(翻译)

Django支持WebSocket(翻译)
最新回答
饮泣我乐意

2026-07-25 02:58:40

Django支持WebSocket。

  • 背景与需求:

    在处理耗时操作(如几分钟的任务)时,HTTP协议无法实时展示操作进度,导致用户体验不佳。

    WebSocket作为一种全双工通信协议,允许服务器和客户端之间建立持久连接,实现实时数据传输,非常适合需要实时反馈的场景。

  • Django与WebSocket的集成:

    无需额外依赖:Django 3.0及以上版本原生支持ASGI(异步服务器网关接口),无需额外安装库即可支持WebSocket。

    ASGI应用结构:ASGI是Python异步Web服务的规范,允许使用async/await构建支持长期连接的服务。ASGI应用是一个异步函数,接收scope、receive、send三个参数,分别代表请求上下文、接收事件和发送事件。

  • 实现步骤:

    环境准备:

    确保Python版本≥3.6,因为Django 3.0+依赖async和await关键字。

    创建项目目录,设置虚拟环境,并安装Django。

    项目初始化:

    使用django-admin startproject命令创建项目,项目目录中会自动生成asgi.py文件,该文件配置了默认的Django ASGI应用。

    自定义ASGI应用:

    修改asgi.py,将默认的application函数封装为自定义异步函数,以区分HTTP和WebSocket请求。

    对于HTTP请求,继续使用Django的默认处理;对于WebSocket请求,则自定义处理逻辑。

    WebSocket逻辑实现:

    在自定义的WebSocket应用中,通过无限循环监听连接、断开和接收事件。

    处理连接事件时,发送websocket.accept以确认连接;处理断开事件时,跳出循环;处理接收事件时,根据消息内容(如“ping”)返回响应(如“pong!”)。

  • 示例代码:

    # asgi.pyimport osfrom django.core.asgi import get_asgi_applicationos.environ.setdefault('DJANGO_SETTINGS_MODULE', 'websocket_app.settings')django_application = get_asgi_application()async def application(scope, receive, send): if scope['type'] == 'http': await django_application(scope, receive, send) elif scope['type'] == 'websocket': await websocket_application(scope, receive, send) else: raise NotImplementedError(f"Unknown scope type {scope['type']}")# websocket.pyasync def websocket_application(scope, receive, send): while True: event = await receive() if event['type'] == 'websocket.connect': await send({'type': 'websocket.accept'}) elif event['type'] == 'websocket.disconnect': break elif event['type'] == 'websocket.receive': if event['text'] == 'ping': await send({'type': 'websocket.send', 'text': 'pong!'})
  • 部署与配置:

    使用ASGI服务器(如Uvicorn或Daphne)运行Django应用。

    在生产环境中,可能需要配置Nginx等反向代理服务器以转发WebSocket连接,确保WebSocket通信的顺畅。

  • 注意事项:

    确保所有中间件和视图函数都是异步兼容的,以充分利用ASGI的异步特性。

    在处理WebSocket连接时,注意错误处理和资源释放,避免内存泄漏或连接挂起。