在 nginx 中结合 map 指令动态开启 websocket 代理,核心做法是在 http 块中使用 map 根据请求头(如 $http_upgrade)生成一个变量(如 $connection_upgrade),然后在 location 块中将 proxy_set_header connection 设置为该变量。这样做能确保只有携带升级请求头的连接才会被提升为 websocket 长连接,其他普通 http 请求则保持正常的短连接行为。

如何配置 map 实现基于 Upgrade 头的动态切换
通过 map 模块匹配 $http_upgrade 的值,将非空值映射为 upgrade,默认值映射为 close。在 location 中引用此变量设置 Connection 头部,即可实现动态切换。

http {
# 定义 map 块
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name example.com;
location /ws {
proxy_pass http://backend_server;
proxy_http_version 1.1;
# 使用 map 生成的变量
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
}
}
}
为什么必须同时设置 proxy_http_version 和 Upgrade 头
Nginx 默认使用 HTTP/1.0 代理后端,且不会自动透传 Upgrade 头。必须显式设置 proxy_http_version 1.1 以支持协议升级,并手动传递 Upgrade 头,否则后端无法识别 WebSocket 握手请求。

# 关键配置片段 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; # Connection 由 map 控制,此处不再硬编码 # proxy_set_header Connection "upgrade";
当客户端未发送 Upgrade 头时连接状态是什么
当客户端未发送 Upgrade 头时,$http_upgrade 为空字符串,map 将其映射为 close,导致 Connection 头部值为 close。此时 Nginx 与后端的连接遵循 HTTP/1.0 或 HTTP/1.1 的默认短连接行为,请求结束后立即关闭,不会建立 WebSocket 长连接。











