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

如何在Flask中结合Twilio实现异步流处理?

问题描述

我有一个处理Twilio呼叫的基础Flask应用,当Twilio发起呼叫时,请求会进入/test HTTP接口。接口内生成TwiML对话:先通过<Say>动词播报“hello world”,同时启动后台流,使用flask_sock处理WebSocket连接。

对应的Flask路由代码:

from twilio.twiml.voice_response import VoiceResponse, Connect
from flask import Flask, request
from flask_sock import Sock

app = Flask(__name__)
sock = Sock(app)

@app.route('/test', methods=['POST'])
def test():   
    response = VoiceResponse()   
    connect = Connect()   
    connect.stream(url=f'wss://{request.host}/stream')   
    response.say("hello world")   
    response.append(connect)   
    response.pause(length=30)   
    return str(response), 200, {'Content-Type': 'text/xml'}

当流处理函数为同步形式时,一切正常:

@sock.route('/stream')
def stream(ws):    
    do_something()

但改为异步形式后,会触发RuntimeWarning: coroutine 'stream' was never awaited警告,且Socket自动终止(抛出ConnectionError):

@sock.route('/stream')
async def stream(ws):    
    await do_something()

无法手动await这个stream函数,因为它是Twilio触发的WebSocket入口,并非主动调用。应用通过flask run命令启动:

if __name__ == '__main__':
    app.run(debug=True)
解决方法

要实现异步流处理,需解决异步WebSocket的运行环境问题,具体步骤如下:

  1. 替换为支持异步的服务器
    默认的flask run使用Werkzeug开发服务器,它不支持异步WebSocket处理。需要改用Hypercorn或Uvicorn这类异步服务器。

以Hypercorn为例,先安装:

pip install hypercorn

然后用Hypercorn启动应用(假设应用文件名为app.py):

hypercorn app:app --reload
  1. 规范异步WebSocket函数的写法
    异步模式下,WebSocket的收发操作必须使用异步方法,所有IO相关的逻辑也要改为异步并通过await调用。示例如下:
async def do_something(ws_data):
    # 异步处理流数据,比如解析Twilio的语音流事件
    pass

@sock.route('/stream')
async def stream(ws):    
    while True:
        # 异步接收Twilio发送的流数据
        stream_data = await ws.receive()
        # 异步处理数据
        await do_something(stream_data)

关键说明

  • Werkzeug服务器不支持异步WebSocket,必须更换为异步服务器才能运行异步的flask_sock路由。
  • 异步函数内的所有阻塞IO操作(如数据库查询、API调用)都要替换为异步实现,避免阻塞事件循环导致连接异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 03:57:33