大大李 2024-07-05 10:48 采纳率: 0%
浏览 111
已结题

python+flask实现流式api接口的问题

我在python中用flask实现流式api接口的时候,学习到以下代码:

from flask import Flask, Response
import time
app = Flask(__name__)
def generate_data():
    for i in range(10):
        yield f"data: {i}
        time.sleep(1)

@app.route('/stream')
def stream():
    return Response(generate_data(), content_type='text/event-stream')

if __name__ == '__main__':
   app.run(debug=True)

在上面的示例中,为什么在服务器端本地,通过curl http://127.0.0.1:5000/stream可以获得正常流式输出,而在客户端通过域名(例如 https://example.com/stream)从远程客户端访问该接口时,则实现不了流式输出,而是等待所有数据完成后才一次性返回?(我的服务器端环境为Windows Server 2012 R2 + IIS + python3.9)

  • 写回答

31条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-07-05 10:49
    关注
    获得1.00元问题酬金

    引自免费微信小程序:皆我百晓生

    在你遇到的问题中,客户端无法实现流式输出,而是在数据完全准备好后才一次性返回,这通常是由于代理服务器(如IIS,在你的场景中作为Flask应用的前端代理)不支持或未正确配置以转发流式响应导致的。Flask应用本身能够正确生成流式数据,但当它部署在像IIS这样的Web服务器后面时,需要确保IIS正确地传递这些流式响应给客户端,而不是缓冲整个响应体。

    解决方案步骤:

    1. 确保IIS支持HTTP长轮询或SSE(Server-Sent Events)

    对于支持流式传输,你需要确认IIS是否配置为允许HTTP长轮询或直接支持SSE。这通常涉及到调整IIS的缓冲行为,确保它不会缓冲来自应用程序的响应内容。

    2. 配置IIS HTTP响应标头

    为了使IIS正确处理Flask应用产生的流式响应,你需要在IIS中设置特定的HTTP响应标头,主要是Transfer-Encoding: chunkedContent-Type: text/event-stream,以及可能的Cache-Control: no-cache来指示不应缓存响应。

    操作步骤:

    • 打开IIS管理器。
    • 导航至你的站点。
    • 双击"HTTP响应标头"。
    • 在"添加"中,分别添加以下标头:
      • 名称:Transfer-Encoding,值:chunked
      • 名称:Content-Type,值:text/event-stream
      • (可选)名称:Cache-Control,值:no-cache

    3. 检查IIS输出缓存设置

    默认情况下,IIS可能会启用输出缓存,这对于动态内容和流式传输是不理想的。你需要禁用对Flask应用路径的输出缓存。

    • 在IIS管理器中,找到你的站点或应用池。
    • 右键点击选择"输出缓存配置"。
    • 查找并排除你的流式API路径(如/stream)。

    4. 使用URL Rewrite模块(如果适用)

    在某些情况下,使用IIS的URL Rewrite模块可以帮助正确地路由请求和响应,特别是当涉及到特殊HTTP头部和行为时。但针对你的场景,主要是调整上述的响应标头和缓存设置。

    示例代码回顾(保持不变):

    你的Flask应用代码看起来已经正确实现了流式API接口,无需修改:

    from flask import Flask, Response
    import time
    
    app = Flask(__name__)
    
    def generate_data():
        for i in range(10):
            yield f"data: {i}\n\n"  # 注意yield后面多了换行符,这是SSE格式要求
            time.sleep(1)
    
    @app.route('/stream')
    def stream():
        return Response(generate_data(), content_type='text/event-stream')
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    确保完成上述IIS配置更改后,重启IIS服务,并再次尝试从客户端访问流式API。这样应该能解决客户端无法实时接收流式数据的问题。

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 7月13日
  • 创建了问题 7月5日

悬赏问题

  • ¥15 35114 SVAC视频验签的问题
  • ¥15 impedancepy
  • ¥15 在虚拟机环境下完成以下,要求截图!
  • ¥15 求往届大挑得奖作品(ppt…)
  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程
  • ¥20 求这个的原理图 只要原理图
  • ¥15 vue2项目中,如何配置环境,可以在打完包之后修改请求的服务器地址
  • ¥20 微信的店铺小程序如何修改背景图
  • ¥15 UE5.1局部变量对蓝图不可见