bigywater.tech
Flask · 150

WebSocket 与 Flask-SocketIO

Flask-SocketIO 放在 nginx 后面要配什么?没配会怎样?空闲连接会不会被代理掐掉?WebSocket 比 polling 快多少?这篇用真实的 nginx 与 python-socketio 客户端,把答案量出来(基本的握手与房间见第 78 篇)。

polling
缺少 Upgrade 头时默认客户端实际使用的传输方式——连得上但悄悄退化
3.0 秒
proxy_read_timeout 3 秒、ping_interval 25 秒时连接被断开的时间
4.2 倍
经过 nginx 时 polling 相对 websocket 的往返耗时

Upgrade 头

实测 · 本机执行输出
  [没有配置 Upgrade 头]
     只允许 websocket          失败:ConnectionError: Connection error
     默认(polling 再升级)        连接成功,传输方式 polling
  [配置了 proxy_http_version 1.1 + Upgrade + Connection]
     只允许 websocket          连接成功,传输方式 websocket
     默认(polling 再升级)        连接成功,传输方式 websocket

上一篇:Server-Sent Events;下一篇:Flask Test Client。

nginx 是自己起的实例(自签证书)。我第一次测试时给客户端写了自定义的 Host 头,结果 websocket 连接一直失败,去掉后才正常——那是我的测试写法的问题,不是 nginx 的行为。

proxy_read_timeout 与心跳

实测 · 本机执行输出
  ping_interval=25(默认)     空闲 7 秒后客户端是否还连着:False(断开发生在约 3.0 秒)| 服务端日志:['connect transport=websocket', 'disconnect reason=transport close']
  ping_interval=1          空闲 7 秒后客户端是否还连着:True(断开发生在约 7.1 秒)| 服务端日志:['connect transport=websocket']

往返延迟

实测 · 本机执行输出
  websocket  中位数 0.38 ms,p95 0.77 ms
  polling    中位数 1.57 ms,p95 1.88 ms

分步演示

WebSocket 与 Flask-SocketIO
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Python 3.14.7 / Flask 3.1.3 / Werkzeug 3.1.9 / Jinja2 3.1.6 / SQLAlchemy 2.1.1 / gunicorn 26.2.0(都装在自己的虚拟环境里);大多数实验用 Flask 的 test_client(直接调用 WSGI 应用,不经过网络),需要真实 HTTP 时另起 gunicorn 或开发服务器(端口 9600 以上,本机 127.0.0.1);计时用 time.perf_counter,数字每次运行会有小幅抖动。Flask-SocketIO 5.6.1、python-socketio 5.17.0、nginx 1.31.6(自己的配置、非默认端口)
    • 没有验证:多 worker 下的消息队列与粘性会话(第 78 篇看过无 nginx 的情形)、wss 在真实证书下的握手、浏览器端 socket.io-client、负载均衡器的空闲超时、大量连接下 nginx 的 worker_connections
    京ICP备2026067502号-1京公网安备11010502063487号