Nginx反向代理WebSocket
WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。该协议使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。如此强大的协议,从1.3.13版本开始,nginx添加对webdocket反向代理支持,让我们的websocket处理能力大大提升。
nginx配置
nginx.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
worker_processes auto;
error_log /var/log/nginx/error.log info;
events {
worker_connections 1024;
}
# 简单示例
http {
upstream backend {
server 127.0.0.1:8000;
}
location /chat/ {
proxy_pass http://backend;
# 主要websocket代理配置, $http_upgrade是指http协议头部Upgrade的值.
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
|
复杂示例
由于Connection协议头的值取决于Upgrade的值,我们可以利用map模块,动态生成Connection头的值,配置如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
http {
upstream backend {
server 127.0.0.1:8000;
}
# map指令的含义,根据$http_upgrade不同值来对$connection_upgrade变量进行赋值,默认为upgrade;$connection_upgrade可以再后续配置中进行引用即可;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
location /chat/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
}
|
经过以上简单的配置,nginx -s reload后,nginx即可作为websocket反向代理服务器。这段配置的关键在于server配置段中的proxy_http_version、proxy_set_header指令,分别设置http_veresion、Upgrade、Connection头部,从而实现http到webdocket的升级。
超时参数
proxy_send_timeout time 默认值 60s 上下文 http server location 说明 这个指定设置了发送请求给upstream服务器的超时时间。超时设置不是为了整个发送期间,而是在两次write操作期间。 如果超时后,upstream没有收到新的数据,nginx会关闭连接
/etc/nginx/conf.d/websocket.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream websocket {
server localhost:8282; # appserver_ip:ws_port
}
server {
server_name test.enzhico.net;
listen 443 ssl;
location / {
proxy_pass http://websocket;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
ssl_certificate /etc/letsencrypt/live/test.enzhico.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/test.enzhico.net/privkey.pem;
}
|
nginx配置文件详解, 见nginx反向代理WebSocket
map值映射
1
2
3
4
5
|
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
|
表示的是:
如果 $http_upgrade 不为 '’ (空),则 $connection_upgrade 为 upgrade 。
如果 $http_upgrade 为 '’ (空),则 $connection_upgrade 为 close。
参考