websocket与django

这里写自定义目录标题

    • [**1. 配置 `asgi.py` 文件**](#1. 配置 asgi.py 文件)
      • [**`asgi.py` 配置**](#asgi.py 配置)
    • [**2. 配置 WebSocket 路由**](#2. 配置 WebSocket 路由)
      • [**`routing.py` 配置**](#routing.py 配置)
    • [**3. 配置 WebSocket 消费者**](#3. 配置 WebSocket 消费者)
      • [**`consumers.py` 配置**](#consumers.py 配置)
    • [**4. 配置普通 HTTP 视图**](#4. 配置普通 HTTP 视图)
      • [**`views.py` 配置**](#views.py 配置)
      • [**`urls.py` 配置**](#urls.py 配置)
    • [**5. 配置 `settings.py` 文件**](#5. 配置 settings.py 文件)
    • [**6. 启动 Django 项目**](#6. 启动 Django 项目)
      • [**方式 1:使用 Daphne 启动 ASGI 服务器**](#方式 1:使用 Daphne 启动 ASGI 服务器)
      • [**方式 2:使用 Uvicorn 启动 ASGI 服务器**](#方式 2:使用 Uvicorn 启动 ASGI 服务器)
      • [**方式 3:在 PyCharm 中配置运行**](#方式 3:在 PyCharm 中配置运行)
    • [**7. 测试 WebSocket 和 HTTP 请求**](#7. 测试 WebSocket 和 HTTP 请求)
    • **总结**

要在 Django 项目中同时支持 WebSocket普通视图 (HTTP 请求)的访问,你需要正确配置 Django ASGIWSGI 的路由,使得两者可以并行运行。Django Channels 会处理 WebSocket 连接,而传统的 HTTP 请求可以通过 Django 的视图处理。

以下是详细的配置步骤,让你在同一个 Django 项目中同时支持 WebSocket 和传统的 HTTP API 访问:


1. 配置 asgi.py 文件

asgi.py 中,你需要同时配置 HTTP 和 WebSocket 路由。ProtocolTypeRouter 会根据请求的类型来分发请求:

  • HTTP 请求 :使用标准的 Django WSGI 应用处理(get_asgi_application())。
  • WebSocket 请求:通过 Channels 处理 WebSocket 连接。

asgi.py 配置

python 复制代码
# your_project_name/asgi.py

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": get_asgi_application(),  # 处理传统 HTTP 请求
    "websocket": AuthMiddlewareStack(  # 处理 WebSocket 请求
        URLRouter(
            your_app.routing.websocket_urlpatterns  # 配置 WebSocket 路由
        )
    ),
})
  • get_asgi_application() 负责处理所有的 HTTP 请求(GET、POST、PUT 等)。
  • AuthMiddlewareStack 用于 WebSocket 的认证中间件(可以扩展用于 WebSocket 认证)。
  • your_app.routing.websocket_urlpatterns 是你配置 WebSocket 路由的地方。

2. 配置 WebSocket 路由

在你的应用的 routing.py 文件中配置 WebSocket 路由:

routing.py 配置

python 复制代码
# your_app/routing.py

from django.urls import path
from . import consumers

websocket_urlpatterns = [
    path('ws/test/', consumers.TestConsumer.as_asgi()),  # WebSocket 路由
]

这里的 TestConsumer 是 WebSocket 消费者类,负责接收和处理 WebSocket 请求。


3. 配置 WebSocket 消费者

consumers.py 中,你定义了如何处理 WebSocket 连接。以下是一个简单的例子:

consumers.py 配置

python 复制代码
import json
from channels.generic.websocket import AsyncWebsocketConsumer

class TestConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.room_name = 'test_room'
        self.room_group_name = f'chat_{self.room_name}'

        # 加入房间组
        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )

        await self.accept()

    async def disconnect(self, close_code):
        # 离开房间组
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

    async def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']

        # 将消息发送到房间组
        await self.channel_layer.group_send(
            self.room_group_name,
            {
                'type': 'chat_message',
                'message': message
            }
        )

    async def chat_message(self, event):
        message = event['message']

        # 发送消息到 WebSocket
        await self.send(text_data=json.dumps({
            'message': message
        }))
  • connect:处理 WebSocket 连接时的逻辑,加入一个房间。
  • disconnect:处理断开连接时的逻辑。
  • receive:接收来自客户端的消息,并广播给房间内的其他客户端。
  • chat_message:当有消息需要广播时,发送到所有客户端。

4. 配置普通 HTTP 视图

你可以像正常的 Django 项目一样,使用视图来处理普通的 HTTP 请求。

views.py 配置

例如,创建一个简单的视图,返回 JSON 数据:

python 复制代码
# your_app/views.py

from django.http import JsonResponse

def api_view(request):
    return JsonResponse({'message': 'Hello, this is a regular HTTP API'})

urls.py 配置

urls.py 中配置 HTTP 路由:

python 复制代码
# your_app/urls.py

from django.urls import path
from .views import api_view

urlpatterns = [
    path('api/hello/', api_view),  # 普通的 HTTP 接口
]

5. 配置 settings.py 文件

settings.py 文件中,确认配置了 ASGI_APPLICATION,指向 asgi.py 文件:

python 复制代码
# settings.py

ASGI_APPLICATION = 'your_project_name.asgi.application'

如果你打算使用 Redis 作为 WebSocket 的通道层,配置 CHANNEL_LAYERS

python 复制代码
# settings.py

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels_redis.core.RedisChannelLayer",
        "CONFIG": {
            "hosts": [("127.0.0.1", 6379)],  # Redis 服务器地址
        },
    },
}

如果不使用 Redis,可以改用 InMemoryChannelLayer

python 复制代码
CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels.layers.InMemoryChannelLayer",
    },
}

6. 启动 Django 项目

方式 1:使用 Daphne 启动 ASGI 服务器

安装 Daphne:

bash 复制代码
pip install daphne

然后通过 Daphne 启动 Django ASGI 应用:

bash 复制代码
daphne your_project_name.asgi:application

方式 2:使用 Uvicorn 启动 ASGI 服务器

安装 Uvicorn:

bash 复制代码
pip install uvicorn

通过 Uvicorn 启动:

bash 复制代码
uvicorn your_project_name.asgi:application --host 0.0.0.0 --port 8000

方式 3:在 PyCharm 中配置运行

你可以在 PyCharm 中创建一个 Django 配置,确保 ASGI_APPLICATION 配置正确,然后启动 ASGI 服务器。具体步骤如下:

  1. 打开 PyCharm,点击 Run > Edit Configurations
  2. 点击 "+" ,选择 Django Server
  3. 配置你的项目名称、主机和端口。
  4. 设置 Targetyour_project_name.asgi:application
  5. 点击 Run 启动。

7. 测试 WebSocket 和 HTTP 请求

  • WebSocket:可以在浏览器控制台或 Vue 前端应用中,使用 WebSocket 连接:
javascript 复制代码
const socket = new WebSocket('ws://localhost:8000/ws/test/');

socket.onopen = function(event) {
    console.log('WebSocket Connected');
    socket.send(JSON.stringify({ 'message': 'Hello, WebSocket!' }));
};

socket.onmessage = function(event) {
    const data = JSON.parse(event.data);
    console.log('Received:', data.message);
};

socket.onclose = function(event) {
    console.log('WebSocket Closed');
};
  • HTTP 请求 :可以通过浏览器直接访问 http://localhost:8000/api/hello/ 或通过 API 客户端进行调用,验证是否能正常访问传统的 HTTP 路由。

总结

通过配置 asgi.py 中的 ProtocolTypeRouter,你可以在同一个 Django 项目中同时支持:

  1. 普通的 HTTP 视图 :通过 get_asgi_application() 处理。
  2. WebSocket 连接 :通过 Channels 的 URLRouter 和消费者进行处理。

这样,无论是 普通的 HTTP 请求 还是 实时的 WebSocket 连接,都可以并行工作,并且互不干扰。

相关推荐
木mu升38 分钟前
java 局域网 rtsp 取流 WebSocket 推送到前端显示 低延迟
网络·websocket·网络协议
Jinxiansen02111 小时前
Vue 3 实战:【加强版】公司通知推送(WebSocket + token 校验 + 心跳机制)
前端·javascript·vue.js·websocket·typescript
工业互联网专业3 小时前
基于django+vue的健身房管理系统-vue
vue.js·python·django·毕业设计·源码·课程设计·健身房管理系统
红鼻子时代3 小时前
Django RBAC项目后端实战 - 03 DRF权限控制实现
后端·python·django·rabc
15942315633 小时前
QT使用WxSQLite3打开加密数据库并查询
数据库·qt·sqlite
CryptoPP15 小时前
使用WebSocket实时获取印度股票数据源(无调用次数限制)实战
后端·python·websocket·网络协议·区块链
zhangsan093316 小时前
web框架(Django 与 FastAPI)
django·fastapi
Python智慧行囊19 小时前
Python 中 Django 中间件:原理、方法与实战应用
python·中间件·架构·django·开发
GoodStudyAndDayDayUp1 天前
初入 python Django 框架总结
数据库·python·django
coderSong25681 天前
Java高级 |【实验八】springboot 使用Websocket
java·spring boot·后端·websocket