就上下文而言,我当前使用的 Azure 环境具有以下核心组件:
Azure APIM > Application Gateway > Web Application Firewall > Vnet > ASE > App Service
应用程序服务托管使用 SignalR 的 .NET 6 API。我用于测试的客户端是 .NET 6 控制台应用程序。
尝试使用 SignalR 通过上述设置连接客户端应用程序时,WebSocket 连接尝试失败并出现以下错误:
Failed to start connection. Error starting transport 'WebSockets'. System.Net.WebSockets.WebSocketException (0x80004005): The server's response was missing the required header 'Connection'.
SignalR 然后尝试回退以使用服务器发送的事件,但它挂起大约 15 秒,然后抛出以下异常:
The underlying connection closed while processing the handshake response. See exception for details. System.IO.IOException: The server disconnected before the handshake could be started.
在数十次对此进行测试的尝试中,SignalR 有两次成功地退回到长轮询,并且效果良好。但我还没有明确任何模式来解释为什么它在这两次情况下起作用。即使我这样做了,我仍然想让 WebSocket 方法正常工作。
查看 APIM 中的日志,后端或 APIM 本身没有抛出任何错误:
前两个请求对应于尝试的 WebSocket 连接,即使它们返回成功的响应,客户端仍然将其解释为失败的响应。我认为这是因为缺少标头,但是我在防火墙、网关或 APIM 上没有找到任何将从响应中删除标头的设置。
最后两个响应对应于尝试使用服务器发送的事件,这里同样,响应都是 200 OK,但客户端将其视为服务器断开连接。
如果我将 APIM 排除在外,并将请求直接发送到应用程序网关公开的公共 URL,则可以通过 WebSocket 建立良好的连接。我还测试了一个连接,该连接进入 APIM > 应用服务,没有网关或其他网络限制,并且也可以正常工作,没有任何问题。
如有任何帮助,我们将不胜感激。