forked from erp-dev/erp
96 lines
3.0 KiB
Python
96 lines
3.0 KiB
Python
"""
|
|
极简SSE实现 - 专注于快速关闭
|
|
关键原则:
|
|
1. 不使用任何全局状态或复杂的队列系统
|
|
2. 使用最短的超时时间
|
|
3. 依靠HTTP连接的自然断开机制
|
|
"""
|
|
import json
|
|
import time
|
|
import signal
|
|
import threading
|
|
from django.http import HttpResponse
|
|
from django.views.decorators.csrf import csrf_exempt
|
|
|
|
# 简单的全局关闭标志
|
|
shutdown_requested = threading.Event()
|
|
|
|
def trigger_shutdown():
|
|
"""触发全局关闭"""
|
|
shutdown_requested.set()
|
|
|
|
def is_shutdown_requested():
|
|
"""检查是否请求关闭"""
|
|
return shutdown_requested.is_set()
|
|
|
|
@csrf_exempt
|
|
def minimal_sse_view(request):
|
|
"""极简SSE视图 - 专注于快速响应关闭信号"""
|
|
|
|
if request.method == 'OPTIONS':
|
|
response = HttpResponse()
|
|
origin = request.META.get('HTTP_ORIGIN')
|
|
if origin:
|
|
response['Access-Control-Allow-Origin'] = origin
|
|
response['Access-Control-Allow-Methods'] = 'GET, OPTIONS'
|
|
response['Access-Control-Allow-Headers'] = 'authorization, content-type'
|
|
response['Access-Control-Allow-Credentials'] = 'true'
|
|
return response
|
|
|
|
def quick_stream():
|
|
"""快速响应的流生成器"""
|
|
try:
|
|
# 发送连接消息
|
|
yield f"data: {json.dumps({'type': 'connected', 'time': time.time()})}\n\n"
|
|
|
|
# 极短循环 - 每0.2秒检查关闭信号
|
|
counter = 0
|
|
while not shutdown_requested.is_set():
|
|
counter += 1
|
|
|
|
# 每5次循环(1秒)发送心跳
|
|
if counter % 5 == 0:
|
|
yield f": heartbeat\n\n"
|
|
|
|
# 非常短的睡眠,快速响应关闭
|
|
time.sleep(0.2)
|
|
|
|
# 最多运行100次循环(20秒)后自动断开,防止永久阻塞
|
|
if counter > 100:
|
|
break
|
|
|
|
# 发送关闭消息
|
|
yield f"data: {json.dumps({'type': 'closing'})}\n\n"
|
|
|
|
except GeneratorExit:
|
|
pass
|
|
except Exception as e:
|
|
print(f"SSE stream error: {e}")
|
|
|
|
response = HttpResponse(quick_stream(), content_type='text/event-stream')
|
|
response['Cache-Control'] = 'no-cache, no-store'
|
|
response['Connection'] = 'close' # 明确告诉客户端这是短连接
|
|
|
|
origin = request.META.get('HTTP_ORIGIN')
|
|
if origin:
|
|
response['Access-Control-Allow-Origin'] = origin
|
|
response['Access-Control-Allow-Credentials'] = 'true'
|
|
|
|
return response
|
|
|
|
|
|
# 注册简单的信号处理器
|
|
def setup_minimal_handlers():
|
|
def handle_shutdown(signum, frame):
|
|
print(f"Minimal SSE: received signal {signum}")
|
|
trigger_shutdown()
|
|
|
|
signal.signal(signal.SIGTERM, handle_shutdown)
|
|
signal.signal(signal.SIGINT, handle_shutdown)
|
|
|
|
# 立即设置处理器
|
|
try:
|
|
setup_minimal_handlers()
|
|
print("Minimal SSE handlers registered")
|
|
except:
|
|
pass |