求同时支持HTTP与WebSocket的Django Channels AsyncHTTPConsumer示例
Django Channels WebSocket + 异步下载的ASGI配置方案
核心思路
ASGI原生支持多协议共存,通过ProtocolTypeRouter可同时处理HTTP(含异步下载)和WebSocket请求。Django 3.1+已原生支持异步视图,Channels负责WebSocket路由,两者能无缝整合到同一ASGI应用中。
1. 修改ASGI配置文件(asgi.py)
在原有Channels配置基础上,保留HTTP协议路由指向Django的ASGI应用,同时维护WebSocket路由配置:
import os from django.core.asgi import get_asgi_application from channels.routing import ProtocolTypeRouter, URLRouter from channels.auth import AuthMiddlewareStack import your_app.routing # 替换为你的WebSocket路由模块 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'your_project.settings') application = ProtocolTypeRouter({ # 处理所有HTTP请求(包括异步下载视图) "http": get_asgi_application(), # 处理WebSocket请求 "websocket": AuthMiddlewareStack( URLRouter( your_app.routing.websocket_urlpatterns ) ), })
2. 编写异步下载视图
使用Django异步视图+aiofiles实现流式异步下载,避免大文件占用过多内存:
import aiofiles from django.http import StreamingHttpResponse from django.views import View # 函数式异步视图 async def async_file_download(request): file_path = "/absolute/path/to/your/file" # 替换为实际文件路径 file_name = "your_file_name.ext" # 下载后的文件名 # 异步流式读取文件 async def file_streamer(): async with aiofiles.open(file_path, 'rb') as f: while chunk := await f.read(8192): # 按8KB块读取 yield chunk response = StreamingHttpResponse(file_streamer(), content_type='application/octet-stream') response['Content-Disposition'] = f'attachment; filename="{file_name}"' return response # 类式异步视图(可选) class AsyncFileDownloadView(View): async def get(self, request): file_path = "/absolute/path/to/your/file" file_name = "your_file_name.ext" async def file_streamer(): async with aiofiles.open(file_path, 'rb') as f: while chunk := await f.read(8192): yield chunk response = StreamingHttpResponse(file_streamer(), content_type='application/octet-stream') response['Content-Disposition'] = f'attachment; filename="{file_name}"' return response
3. 配置HTTP路由
在应用的urls.py中添加异步下载路由,和普通路由配置一致:
from django.urls import path from .views import async_file_download, AsyncFileDownloadView urlpatterns = [ # 函数式视图路由 path('download/async/', async_file_download, name='async_file_download'), # 类式视图路由(可选) path('download/async/class/', AsyncFileDownloadView.as_view(), name='async_file_download_class'), # 其他路由... ]
4. 依赖与验证
- 安装必要依赖:
pip install channels aiofiles - 启动ASGI服务器:使用Daphne或Uvicorn,例如
daphne your_project.asgi:application - 验证:
- 访问
/download/async/测试异步下载功能 - 使用WebSocket客户端连接你的WS路由(如
ws://localhost:8000/ws/your-path/)验证WebSocket功能
- 访问
内容的提问来源于stack exchange,提问作者800c25d6-cd74-11ed-afa1-0242ac
相关产品推荐
相关产品推荐

