不修改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。

🔎

延伸解读

WebSocket与nginx的兼容性问题

WebSocket协议依赖于Upgrade头来实现协议升级,但nginx的配置可能会吞掉这个头,导致请求无法正确匹配。理解这一点对于开发者在使用nginx作为反向代理时,确保WebSocket功能正常至关重要。

uvicorn的请求处理流程

在uvicorn中,请求的处理流程决定了如何识别WebSocket请求。开发者需要注意,只有在请求到达时正确识别Upgrade头,才能将请求标记为websocket scope,否则将无法匹配相应的路由。

修改TCP字节的复杂性

作者通过直接修改uvicorn接收到的TCP字节来解决问题,这种方法虽然有效,但相对复杂且不易维护。开发者在选择解决方案时,应权衡复杂性与可维护性,考虑是否有更简单的替代方案。

延伸问答

如何在不修改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的兼容。

🏷️

标签

➡️

继续阅读