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

应用程序网关跨所有网关大小为 WebSocket 提供本机支持。 用户无法通过配置设置来选择性地启用或禁用 WebSocket 支持。

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

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

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

WebSocket 工作原理

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

Diagram compares a client interacting with a web server, connecting twice to get two replies, with a WebSocket interaction, where a client connects to a server once to get multiple replies.

注意

如前所述,HTTP 协议只用于在建立 WebSocket 连接时执行握手。 在握手完成后,将打开 WebSocket 连接以传输数据,Web 应用程序防火墙 (WAF) 无法分析任何内容。 因此,WAF 不会对此类数据执行任何检查。

侦听器配置元素

现有的 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 和路由规则配置

如果后端池具有已启用 WebSocket 的服务器,那么使用 BackendAddressPool 对其进行定义。 使用后端端口 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 应用程序。