不修改nginx接收websocket

💡 原文中文,约3100字,阅读约需8分钟。
📝

内容提要

文章讨论了如何在不修改nginx配置的情况下支持WebSocket。通过分析FastAPI和uvicorn的请求处理流程,发现nginx会吞掉Upgrade头,导致WebSocket请求无法正确匹配。作者通过修改uvicorn的TCP字节处理方式,成功实现了WebSocket的兼容,尽管方法较为复杂。

🎯

关键要点

  • WebSocket协议的工作方式包括客户端发送GET请求和Upgrade头,服务端返回101 Switching Protocols。

  • nginx会吞掉Upgrade头,导致uvicorn将请求标记为HTTP scope,从而无法匹配WebSocket路由。

  • 作者尝试通过ASGI中间件和gunicorn配置来解决问题,但发现标准ASGI中间件无法在请求到达时修改scope类型。

  • 最终,作者通过直接修改uvicorn接收到的TCP字节,成功实现了在不修改nginx配置的情况下支持WebSocket。

延伸问答

如何在不修改nginx配置的情况下支持WebSocket?

可以通过修改uvicorn的TCP字节处理方式来实现WebSocket的兼容,而不需要更改nginx的配置。

nginx吞掉Upgrade头的原因是什么?

nginx吞掉Upgrade头是因为它未能正确透传WebSocket请求,导致uvicorn将请求标记为HTTP scope。

WebSocket协议的工作流程是怎样的?

WebSocket协议的工作流程包括客户端发送GET请求和Upgrade头,服务端返回101 Switching Protocols以完成连接升级。

为什么uvicorn无法匹配WebSocket路由?

因为nginx吞掉了Upgrade头,导致uvicorn将请求标记为HTTP scope,从而无法匹配WebSocket路由。

作者使用了哪些方法尝试解决WebSocket兼容性问题?

作者尝试了ASGI中间件和gunicorn配置,但最终通过直接修改uvicorn接收到的TCP字节成功解决了问题。

修改uvicorn的TCP字节处理方式具体是怎样的?

作者通过篡改uvicorn收到的原始TCP字节,添加Upgrade头和Connection头,从而实现WebSocket的兼容。

➡️

继续阅读