从昨天开始,我们就遇到了 WebSocket 连接问题。基于 chromium 的浏览器和 Firefox 在连接期间不会将
Sec-WebSocket-Key
添加到标头中。我们使用标准的 new WebSocket()
来连接服务器。
缺少标题
Sec-WebSocket-Key
标题
有趣的是,当我打开一个新的隐身窗口时,我可以创建一个连接,但在一些
fetch()
请求之后,如果我尝试建立另一个连接,它将失败 - 缺少 Sec-Websocket-Key
标头。
Nginx 配置
/ws
。
location ^~ /ws {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://backend;
}
有人遇到过类似的问题吗?
已在 Windows、Linux 和 Mac 上检查 Google Chrome 版本 96.0.4664.93 和 Firefox 95.0.1。
MacOS 和 Safari 均可使用。
问题可能出在 Firefox 和 Chrome 中的 HTTP2 实现(Safari 工作正常)。我们挖掘了三天,终于意识到禁用 HTTP2 后问题就消失了。
这是DigitalOcean技术支持的回复:
我们最近启用了对 HTTP2 上的 Websocket 的支持 (RFC 8441)。 这增加了对浏览器重用现有 HTTP2 连接的支持 并将允许通过 HTTP2 建立 WebSocket 连接隧道 溪流。作为立即修复的一部分,我们已禁用此功能 通知浏览器通过 HTTP1.1 创建 Websocket 的功能 (RFC 6455)。我们相信该错误实际上存在于 Chrome/Firefox 中,但是 需要进一步测试来找出问题所在。据我们所知 LB 不是问题,因为浏览器不包括 所需的标头 Sec-WebSocket-Key。
我们也遇到了类似的问题。
SETTINGS_ENABLE_CONNECT_PROTOCOL:1
,这表明支持基于 HTTP/2 (RFC 8441) 的 WebSockets。Sec-WebSocket-Key
是非必需。问题是 Chrome 尝试通过 HTTP/2 使用 WebSocket。 Sec-WebSocket-Key
缺失只是一方面。SETTINGS_ENABLE_CONNECT_PROTOCOL:1
。我们联系了我们的 CDN 提供商,他们禁用了
SETTINGS_ENABLE_CONNECT_PROTOCOL:1
,错误就不再发生了。