""" 极简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