应用程序网关中的 WebSocket 支持概述

应用程序网关在所有网关规格下均原生支持 WebSocket。 用户无法通过配置设置来选择性地启用或禁用 WebSocket 支持。

RFC6455 中标准化的 WebSocket 协议可通过持久 TCP 连接使服务器与客户端之间能够进行全双工通信。 此功能让 Web 服务器和客户端之间能够进行交互性更强的通信。这种通信可以是双向的,而且不像基于 HTTP 的实现那样需要轮询。 不同于 HTTP,WebSocket 的开销很低,并且可以对多个请求/响应重复使用同一 TCP 连接,进而提高资源利用率。 WebSocket 协议设计为通过传统 HTTP 端口 80 和 443 运行。 应用程序网关支持最多 30,000 个并发 WS 连接和每个实例 13,500 个 WSS 连接。

可以在端口 80 或 443 上继续使用标准 HTTP 侦听器来接收 WebSocket 流量。 随后会使用应用程序网关规则中指定的相应后端池,将 WebSocket 流量定向到已启用 WebSocket 的后端服务器。 后端服务器必须响应应用程序网关探测,如运行状况探测概述部分中所述。 应用程序网关运行状况探测仅适用于 HTTP/HTTPS。 每个后端服务器都必须响应 HTTP 探测器,以便应用程序网关将 WebSocket 流量路由到服务器。

它用在受益于快速实时通信的应用(例如聊天、仪表板和游戏应用)中。

WebSocket 工作原理

若要建立 WebSocket 连接,需在客户端和服务器之间交换特定的基于 HTTP 的握手。 如果成功,则应用程序层协议会使用之前建立的 TCP 连接从 HTTP“升级”为 WebSocket。 然后就完全不使用 HTTP;两个终结点可以使用 WebSocket 协议来发送或接收数据,直至 WebSocket 连接关闭。

此图将与 Web 服务器进行的客户端交互(连接两次以获得两个答复)与 WebSocket 交互(客户端连接到服务器一次即可获得多个答复)进行比较。

注意

将连接升级到 WebSocket(作为中介/终止代理)后,应用程序网关只需将数据从前端发送到后端,反之亦然,无需任何检查或操作功能。 因此,Web 应用程序防火墙(WAF)无法分析任何内容,也不会对此类数据执行任何检查。 同样,在建立 WebSocket 连接后,后端设置中的任何操作(如标头重写、URL 重写或重写主机名)都不适用。

侦听器配置元素

现有的 HTTP 侦听器可用于支持 WebSocket 流量。 以下代码片段显示了示例模板文件中的元素 httpListeners 。 需要 HTTP 和 HTTPS 侦听器才能支持 WebSocket 和安全 WebSocket 流量。 同样,可以使用门户或Azure PowerShell在端口 80 和 443 上使用侦听器创建应用程序网关,以支持 WebSocket 流量。

"httpListeners": [
        {
            "name": "appGatewayHttpsListener",
            "properties": {
                "FrontendIPConfiguration": {
                    "Id": "/subscriptions/{subscriptionId/resourceGroups/{resourceGroupName/providers/Microsoft.Network/applicationGateways/{applicationGatewayName/frontendIPConfigurations/DefaultFrontendPublicIP"
                },
                "FrontendPort": {
                    "Id": "/subscriptions/{subscriptionId/resourceGroups/{resourceGroupName/providers/Microsoft.Network/applicationGateways/{applicationGatewayName/frontendPorts/appGatewayFrontendPort443'"
                },
                "Protocol": "Https",
                "SslCertificate": {
                    "Id": "/subscriptions/{subscriptionId/resourceGroups/{resourceGroupName/providers/Microsoft.Network/applicationGateways/{applicationGatewayName/sslCertificates/appGatewaySslCert1'"
                },
            }
        },
        {
            "name": "appGatewayHttpListener",
            "properties": {
                "FrontendIPConfiguration": {
                    "Id": "/subscriptions/{subscriptionId/resourceGroups/{resourceGroupName/providers/Microsoft.Network/applicationGateways/{applicationGatewayName/frontendIPConfigurations/appGatewayFrontendIP'"
                },
                "FrontendPort": {
                    "Id": "/subscriptions/{subscriptionId/resourceGroups/{resourceGroupName/providers/Microsoft.Network/applicationGateways/{applicationGatewayName/frontendPorts/appGatewayFrontendPort80'"
                },
                "Protocol": "Http",
            }
        }
    ],

BackendAddressPool、BackendHttpSetting 和路由规则配置

使用 BackendAddressPool 定义启用了 WebSocket 的服务器的后端池。 使用后端端口 80 和 443 定义 backendHttpSetting。 HTTP 设置中的请求超时值也适用于 WebSocket 会话。 无需更改路由规则,该规则会将相应的侦听器绑定到相应的后端地址池。

"requestRoutingRules": [{
    "name": "<ruleName1>",
    "properties": {
        "RuleType": "Basic",
        "httpListener": {
            "id": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/applicationGateways/{applicationGatewayName}/httpListeners/appGatewayHttpsListener')]"
        },
        "backendAddressPool": {
            "id": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/applicationGateways/{applicationGatewayName}/backendAddressPools/ContosoServerPool')]"
        },
        "backendHttpSettings": {
            "id": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/applicationGateways/{applicationGatewayName}/backendHttpSettingsCollection/appGatewayBackendHttpSettings')]"
        }
    }

}, {
    "name": "<ruleName2>",
    "properties": {
        "RuleType": "Basic",
        "httpListener": {
            "id": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/applicationGateways/{applicationGatewayName}/httpListeners/appGatewayHttpListener')]"
        },
        "backendAddressPool": {
            "id": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/applicationGateways/{applicationGatewayName}/backendAddressPools/ContosoServerPool')]"
        },
        "backendHttpSettings": {
            "id": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/applicationGateways/{applicationGatewayName}/backendHttpSettingsCollection/appGatewayBackendHttpSettings')]"
        }

    }
}]

注意

确保超时值大于服务器定义的 ping/pong 间隔,以避免在从客户端发送 ping 之前遇到超时错误。 WebSocket 的典型值为 20 秒,因此,例如,超时值 40 秒可确保网关在客户端发送 ping 之前不会发送超时错误。 否则,此条件会在客户端引发 1006 错误。

已启用 WebSocket 的后端

后端必须在配置的端口(通常为 80 或 443)上运行 HTTP/HTTPS Web 服务器才能运行 WebSocket。 存在此要求,因为 WebSocket 协议要求初始握手是 HTTP,并将 WebSocket 协议升级为标头字段。 以下示例显示了一个标头:

    GET /chat HTTP/1.1
    Host: server.example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Origin: https://example.com
    Sec-WebSocket-Protocol: chat, superchat
    Sec-WebSocket-Version: 13

此要求的另一个原因是应用程序网关后端运行状况探测仅支持 HTTP 和 HTTPS 协议。 如果后端服务器未响应 HTTP 或 HTTPS 探测,网关会将其从后端池中删除。

后续步骤

了解 WebSocket 支持后,请转到 创建应用程序网关 以开始使用已启用 WebSocket 的 Web 应用程序。