如何在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的运行环境问题,具体步骤如下:
- 替换为支持异步的服务器
默认的flask run使用Werkzeug开发服务器,它不支持异步WebSocket处理。需要改用Hypercorn或Uvicorn这类异步服务器。
以Hypercorn为例,先安装:
pip install hypercorn
然后用Hypercorn启动应用(假设应用文件名为app.py):
hypercorn app:app --reload
- 规范异步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
相关产品推荐
相关产品推荐

