WebSocket 是基于 HTTP 协议,为 Web 应用提供的实时双向通讯协议。自从发布以来,越来越多的浏览器和服务端软件都已经支持了 WebSocket 。
当我们使用 nginx 作为 HTTP 接入层时,却会发现默认情况下,WebSocket 通讯会失败。这是因为 nginx 的配置默认情况下不支持 WebSocket,需要额外的配置才能支持 WebSocket。
当客户端发起 WebSocket 请求时,会首先尝试建议连接,此时使用的请求地址并不是普通的 http://
或https://
开头的地址,而是以 ws://
(未经TLS加密,与HTTP对应)或 wss://
(经TLS加密,与HTTPS对应)开头的地址。
请求头:
GET /websocket HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: ziSCLxp0qEtHUb7wQBcq/A==
Origin: http://example.com
Sec-WebSocket-Version: 13
可见,该请求头与普通的 HTTP 请求头非常类似,除了多几个字段:
Upgrade
:必须为 websocket
,表示需要升级协议为 WebSocket
进行通讯
Connection
:必须为 Upgrade
,表示需要升级连接
Sec-WebSocket-Key
:必须为随机字符串,用于握手验证,服务器也会返回一个类似的字符串
响应头:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: xmiI8OZ9IrGkCJR+xOo=
经过这样的握手,双方就可以建立 WebSocket 连接,进行实时双向通讯了。
配置 WebSocket 反向代理
nginx 反向代理 WebSocket 的话,需要明确地添加 Upgrade
和 Connection
头:
server {
...
location /websocket {
proxy_pass http://localhost:19001;
proxy_http_version 1.1;
proxy_set_header Host $host;
# 添加了websocket支持
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# websocket配置完成
}
}
通过以上配置,nginx 就可以正常代理 WebSocket 请求了。