如何在Django中检测客户端连接关闭?(SSE长连接场景)
检测Django长连接(SSE)客户端断开连接的方法
在Django中处理流式响应(比如SSE)时,客户端关闭连接会触发**管道破裂(Broken Pipe)**相关的异常,你可以通过在响应生成逻辑中捕获这些异常来检测连接断开事件。
核心思路
当客户端断开连接后,服务器尝试向连接写入数据时会抛出BrokenPipeError(Python3)或IOError(Python2),部分场景下还可能出现ConnectionResetError。在流式响应的生成循环中捕获这些异常,即可执行连接断开后的清理逻辑。
代码示例
以下是一个SSE流式响应的视图示例,包含连接断开检测:
from django.http import StreamingHttpResponse import time def sse_stream(request): def event_stream(): try: count = 0 while True: # 生成SSE格式的消息 yield f"data: {count}\n\n" count += 1 time.sleep(1) except (BrokenPipeError, ConnectionResetError, IOError) as e: # 捕获到连接断开异常,执行自定义清理逻辑 print(f"客户端连接已断开: {e}") # 这里可添加资源释放、状态更新等操作 # 若不需要Django记录异常日志,可删除下面的raise语句 raise response = StreamingHttpResponse(event_stream(), content_type='text/event-stream') response['Cache-Control'] = 'no-cache' response['Connection'] = 'keep-alive' return response
补充说明
- 不同WSGI服务器(如Gunicorn、uWSGI)处理连接断开时的异常表现略有差异,建议同时捕获
BrokenPipeError、ConnectionResetError和IOError以覆盖多数场景。 - 若使用Django异步视图(ASGI模式),逻辑类似,只需在异步生成器中捕获对应的异步IO异常即可。
- 捕获异常后,可根据需求选择是否重新抛出:重新抛出会让Django记录你看到的管道破裂日志,不抛出则仅执行自定义清理逻辑。
内容的提问来源于stack exchange,提问作者Wrystal
相关产品推荐
相关产品推荐

