You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI SSE端点关闭客户端后sse-starlette生成器卡住问题

解决FastAPI SSE客户端断开后生成器阻塞的问题

问题根源

FastAPI的SSE生成器无法主动感知客户端断开,若生成器仅阻塞在asyncio.sleep()步骤,没有向客户端发送数据的操作,就无法触发连接断开的异常检测,导致生成器一直阻塞。

具体解决方案

1. 添加心跳检测并捕获发送异常

定期发送心跳消息,利用发送操作触发连接断开的异常,从而退出生成器:

from fastapi import FastAPI, Request
from fastapi.responses import StreamingResponse
import asyncio

app = FastAPI()

async def sse_generator(request: Request):
    while True:
        try:
            # 发送心跳事件(空内容或标识心跳的文本)
            yield "event: heartbeat\n\n"
            await asyncio.sleep(5)
        except Exception:
            # 客户端断开时发送操作会抛出异常,直接退出循环
            print("客户端已断开,生成器退出")
            break

@app.get("/sse")
async def sse_endpoint(request: Request):
    return StreamingResponse(
        sse_generator(request),
        media_type="text/event-stream"
    )

2. 主动检查连接状态

利用FastAPI提供的request.is_disconnected()方法,在每次循环时主动检测连接状态:

async def sse_generator(request: Request):
    try:
        while True:
            # 先检查连接是否存活
            if await request.is_disconnected():
                break
            yield "data: 实时更新内容\n\n"
            await asyncio.sleep(5)
    finally:
        print("生成器已退出")

注意:部分场景下连接断开后is_disconnected()可能不会立即返回True,配合发送操作检测更可靠。

3. 避免长时间阻塞sleep

如果需要长时间休眠,用asyncio.wait()同时等待sleep完成和连接断开事件,避免阻塞:

async def sse_generator(request: Request):
    while True:
        # 创建sleep任务,同时监听连接状态
        sleep_task = asyncio.create_task(asyncio.sleep(30))
        disconnect_check = asyncio.create_task(request.is_disconnected())
        
        done, pending = await asyncio.wait(
            [sleep_task, disconnect_check],
            return_when=asyncio.FIRST_COMPLETED
        )
        
        # 若连接已断开,清理任务并退出
        if await request.is_disconnected():
            for task in pending:
                task.cancel()
            print("客户端断开,退出生成器")
            break
        
        # 连接正常,发送数据并清理任务
        yield "data: 延迟更新内容\n\n"
        for task in pending:
            task.cancel()

环境适配注意事项

  • 确保FastAPI版本≥0.68.0,Python 3.8对asyncio的支持完全适配Ubuntu 20.04环境
  • 测试时直接关闭客户端标签/进程,避免仅刷新页面(部分浏览器会复用连接)

内容的提问来源于stack exchange,提问作者Mark

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 20:21:38