1
0
forked from erp-dev/erp
Files
erpnew/sse

SSE (Server-Sent Events) 模块

基于 Django REST Framework 的服务器推送事件实现。

功能特性

  • 使用 DRF 处理请求和响应
  • 支持多种请求格式JSON、Form Data、Multipart
  • 自动数据验证和序列化
  • 异步支持,高并发处理
  • 心跳机制保持连接活跃
  • 自动清理断开的连接
  • 连接状态监控

API 端点

1. 订阅 SSE 事件流

端点: GET /sse/

客户端连接此端点保持长连接,接收服务器推送的事件。

示例:

curl -N http://localhost:8000/sse/

JavaScript 示例:

const eventSource = new EventSource('http://localhost:8000/sse/');

eventSource.onmessage = function(event) {
    const data = JSON.parse(event.data);
    console.log('收到消息:', data);
};

2. 推送事件到所有客户端

端点: POST /sse/push/

向所有已连接的客户端广播消息。

请求参数:

  • message (必填): 消息内容
  • type (可选): 事件类型,默认为 'message'

支持的请求格式:

JSON 格式

curl -X POST http://localhost:8000/sse/push/ \
  -H "Content-Type: application/json" \
  -d '{"message": "Hello, SSE!", "type": "notification"}'

Form Data 格式

curl -X POST http://localhost:8000/sse/push/ \
  -d "message=Hello, SSE!" \
  -d "type=notification"

Multipart Form Data

curl -X POST http://localhost:8000/sse/push/ \
  -F "message=Hello, SSE!" \
  -F "type=notification"

响应示例:

{
    "status": "success",
    "message": "Event sent to 3 client(s)",
    "clients": 3,
    "sent": 3
}

3. 获取连接状态

端点: GET /sse/status/

查询当前 SSE 服务器的状态和连接数。

示例:

curl http://localhost:8000/sse/status/

响应示例:

{
    "status": "running",
    "clients": 3,
    "message": "SSE server is running with 3 active connection(s)"
}

启动服务器

使用 Uvicorn (ASGI 服务器) 启动:

# 开发环境
uvicorn flower.asgi:application --reload --host 0.0.0.0 --port 8000

# 生产环境
uvicorn flower.asgi:application --host 0.0.0.0 --port 8000 --workers 4

测试

打开 sse_test.html 在浏览器中测试:

  1. 点击"连接 SSE"建立连接
  2. 输入消息
  3. 点击"发送 (JSON)"或"发送 (Form Data)"测试不同格式
  4. 点击"获取连接状态"查看当前连接数
  5. 打开多个浏览器标签测试广播功能

Python 客户端示例

import requests
import sseclient  # pip install sseclient-py

# 订阅事件
response = requests.get('http://localhost:8000/sse/', stream=True)
client = sseclient.SSEClient(response)

for event in client.events():
    print(f'收到消息: {event.data}')

技术实现

  • 异步视图: 使用 async def 实现异步处理
  • 队列机制: 每个连接对应一个 asyncio.Queue
  • 心跳: 30 秒超时,自动发送心跳保持连接
  • DRF 集成: 使用 DRF 的 @api_view 和序列化器
  • 多格式支持: 自动解析 JSON、Form Data、Multipart 等格式

注意事项

  1. 必须使用 ASGI 服务器(如 Uvicorn、Daphne运行
  2. 不支持使用传统的 WSGI 服务器(如 Gunicorn + WSGI
  3. 如果使用 Nginx需要禁用缓冲X-Accel-Buffering: no
  4. SSE 使用 GET 请求,注意 CORS 配置