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

FastAPI中WebSocket在Docker环境下无法实时返回数据问题

Docker环境下FastAPI WebSocket实时推送进度失效问题解决

问题背景

开发基于Whisper AI的音频转录API,通过FastAPI WebSocket实现转录进度实时推送。本地Windows环境用uvicorn main:app --reload运行时,前端可正常实时展示进度;但部署到Docker容器后,WebSocket需等待转录进程完全结束才一次性返回所有进度数据。Docker日志能实时打印进度内容,说明print语句执行正常,但await websocket.send_text()未实时生效。已尝试websocket.send_bytes()、设置websocket.write_buffer_size=0等方法,问题仍存在。

相关代码

WebSocket实现代码

@app.websocket("/ws/transcribe")
async def transcribe_websocker(websocket: WebSocket):
    
    await websocket.accept()
    process = subprocess.Popen(['python', 'ai.py'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, shell=False)
    
    while True:
        line = process.stdout.readline()
        if not line:
            break

        # Encode and send the line to the WebSocket client
        encoded_line = line.encode('utf-8')
        print(f"logs: {encoded_line}")
        await websocket.send_text(encoded_line)

    # Close the process and the WebSocket connection
    process.stdout.close()
    process.wait()
    await websocket.close()

Dockerfile配置

FROM python:3.10-slim

WORKDIR /python-docker

RUN apt-get update && apt-get install git -y

RUN pip3 install fastapi
RUN pip3 install "uvicorn[standard]"
RUN pip3 install -U git+https://github.com/jianfch/stable-ts.git
RUN apt-get install -y ffmpeg
RUN pip3 install moviepy
RUN pip3 install streaming_form_data
RUN pip3 install websockets

COPY . .

ENV PYTHONUNBUFFERED=1

#COPYING MODELS
COPY base.pt /root/.cache/whisper/base.pt

EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

解决方案

1. 修正WebSocket发送参数类型错误

websocket.send_text()要求传入字符串类型,但原代码中传入了encoded_line(bytes类型),这会导致消息发送异常,在部分环境下可能被缓冲直到连接关闭。修正为直接发送字符串:

# 替换原send_text行
await websocket.send_text(line.strip())

2. 强制子进程无缓冲输出

即使设置了PYTHONUNBUFFERED=1,子进程ai.py的输出仍可能存在缓冲。启动子进程时添加-u参数,强制Python使用无缓冲输出:

process = subprocess.Popen(['python', '-u', 'ai.py'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, shell=False)

同时,在ai.py的打印语句后手动刷新输出,确保进度信息实时写入stdout:

import sys
# 替换ai.py中的print语句
print(progress_content, flush=True)

3. 让出事件循环避免阻塞

Docker环境下事件循环可能被长时间占用,导致WebSocket消息无法及时推送。在发送消息后添加await asyncio.sleep(0),强制让出CPU资源,触发事件循环处理发送操作:

await websocket.send_text(line.strip())
await asyncio.sleep(0)  # 新增此行,需提前import asyncio

4. 调整Uvicorn运行参数

Docker中默认的Uvicorn多worker模式可能导致消息缓冲,指定单worker运行:
修改Dockerfile中的CMD命令:

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "1"]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 14:40:14