应用程序网关中的 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 连接关闭。
注意
将连接升级到 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 和路由规则配置
如果后端池具有已启用 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 应用程序。