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

IIS反向代理部署Flask-SocketIO时WebSocket升级失败问题求助

解决方案步骤

1. 修改IIS反向代理规则,透传WebSocket握手头

现有web.config的入站规则漏了WebSocket必须的Upgrade和Connection头透传,直接替换ReverseProxyInboundRule1规则内容:

<rule name="ReverseProxyInboundRule1" enabled="true" stopProcessing="true">
    <match url="(.*)" />
    <action type="Rewrite" url="http://127.0.0.1:4441/{R:1}" />
    <serverVariables>
        <set name="HTTP_X_FORWARDED_PORT" value="4440" />
        <set name="HTTP_X_FORWARDED_HOST" value="subdomain.domain.co.uk" />
        <set name="HTTP_X_FORWARDED_PROTO" value="https" />
        <!-- 新增以下两行,透传WebSocket握手头 -->
        <set name="HTTP_CONNECTION" value="{HTTP_CONNECTION}" />
        <set name="HTTP_UPGRADE" value="{HTTP_UPGRADE}" />
    </serverVariables>
    <conditions>
        <!-- 新增条件匹配WebSocket升级请求 -->
        <add input="{HTTP_UPGRADE}" pattern="websocket" ignoreCase="true" negate="false" />
    </conditions>
</rule>

配置完成后需要在IIS对应站点的「URL重写」->「查看服务器变量」中,添加HTTP_CONNECTION和HTTP_UPGRADE到允许列表,否则配置不会生效。

2. 禁用IIS对Socket.io路径的压缩和缓冲

在system.webServer节点下新增以下配置,避免WebSocket流量被压缩、缓冲导致连接中断:

<system.webServer>
    <!-- 原有配置保持不变,新增以下内容 -->
    <urlCompression doStaticCompression="true" doDynamicCompression="false" />
    <httpCompression>
        <dynamicTypes>
            <add mimeType="text/*" enabled="false" />
            <add mimeType="application/json" enabled="false" />
            <add mimeType="application/javascript" enabled="false" />
        </dynamicTypes>
    </httpCompression>
    <caching enabled="false" enableKernelCache="false" />
</system.webServer>

3. 调整Flask-SocketIO服务端配置

将ProxyFix中间件的初始化位置调整到socketio.init_app之前,确保SocketIO的请求也能正确获取反向代理的转发信息,同时指定允许的传输方式:

# __init__.py修改后内容
from werkzeug.middleware.proxy_fix import ProxyFix
from flask_socketio import SocketIO

# 先套ProxyFix,再初始化socketio
if not app.debug:
    app.wsgi_app = ProxyFix(app.wsgi_app, x_port=1, x_proto=1, x_host=1)

socketio.init_app(
    app, 
    logger=True, 
    engineio_logger=True, 
    cors_allowed_origins="https://subdomain.domain.co.uk:4440",
    # 新增以下配置,优先走websocket
    transports=['websocket', 'polling'],
    allow_upgrades=True
)

return app

4. 调整客户端初始化配置

明确指定客户端优先使用WebSocket传输,避免无意义的长轮询重试:

$(document).ready(function() {
    // 新增transports参数,指定优先websocket
    var socket = io('/<NAMESPACE>', {
        transports: ['websocket', 'polling'],
        upgrade: true
    });

    socket.on('connect', function() {
        socket.emit('joined', {room: <ROOM_NAME>});
    });
});

5. 验证IIS全局配置

  1. 打开IIS管理器,进入「应用程序请求路由缓存」->「服务器代理设置」,将「超时」值调整为至少120秒,避免长连接被提前断开
  2. 确认站点对应应用池的「托管管道模式」为「集成」,「启用32位应用程序」设置为False
  3. 重启IIS站点和Flask-SocketIO服务后再测试

按照以上步骤配置完成后,即可正常看到Received request to upgrade to websocket的成功日志,WebSocket连接可以正常建立,不会再出现批量长轮询请求和BrokenPipe报错。

内容的提问来源于stack exchange,提问作者lc-51

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 11:15:02