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

如何在FastAPI的StreamingResponse生成器中关闭Socket?

问题分析与解决方案

你的代码里,gen_video用with socket.socket()管理连接,但同步Socket的recv是阻塞调用——当客户端断开连接时,FastAPI的StreamingResponse会停止迭代生成器,但生成器此时卡在recv上,没法退出循环,导致with块的自动关闭逻辑无法执行,Socket也就不能及时释放。

这里提供两种可行的解决办法:

方法一:给同步Socket设置超时,捕获生成器停止信号

给Socket设置超时,让recv定期跳出阻塞,同时捕获GeneratorExit异常(生成器被停止时抛出),主动触发Socket关闭:

import fastapi
import uvicorn
import socket

def gen_video(port):
    with socket.socket() as s:
        s.settimeout(1.0)  # 设置1秒超时,让recv定期返回
        s.connect(("127.0.0.1", port))
        try:
            while True:
                try:
                    data = s.recv(1024)
                    if not data:  # 数据源主动关闭连接
                        break
                    yield data
                except socket.timeout:
                    continue  # 超时后继续循环,检查是否需要退出
        except GeneratorExit:
            # 客户端断开,生成器被终止,主动关闭Socket(with块最终也会关,这里是提前释放)
            s.close()

app = fastapi.FastAPI()

@app.get("/stream")
async def stream():
    return fastapi.responses.StreamingResponse(gen_video(1234), media_type="video/ogg")

if __name__ == "__main__":
    uvicorn.run(app, port=8000)

方法二:改用异步Socket配合异步生成器(推荐)

FastAPI是异步框架,用asyncio的异步Socket更适配,能更优雅地处理客户端断开的情况:

import fastapi
import uvicorn
import asyncio

async def gen_video(port):
    # 建立异步连接
    reader, writer = await asyncio.open_connection("127.0.0.1", port)
    try:
        while True:
            # 异步读取数据,不会阻塞事件循环
            data = await reader.read(1024)
            if not data:
                break
            yield data
    finally:
        # 无论是否异常,都关闭连接
        writer.close()
        await writer.wait_closed()

app = fastapi.FastAPI()

@app.get("/stream")
async def stream():
    return fastapi.responses.StreamingResponse(gen_video(1234), media_type="video/ogg")

if __name__ == "__main__":
    uvicorn.run(app, port=8000)

异步方式下,当客户端断开,StreamingResponse会停止迭代异步生成器,finally块会立即执行,关闭Socket连接,无需依赖超时机制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 23:45:40