本文中的nginx版本:nginx/1.16.1
话不多说,直接上配置:
server
{
listen 80;
server_name test.css3er.com;
index index.html index.htm index.php;
root /home/wwwroot/default;
autoindex on; #显示目录列表
autoindex_exact_size on; #显示出文件的确切大小,单位是bytes
autoindex_localtime on; #显示的文件时间为文件的服务器时间
#error_page 404 /404.html;
# Deny access to PHP files in specific directory
#location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ { deny all; }
include enable-php.conf;
location /nginx_status
{
stub_status on;
access_log off;
}
# 添加websocket的反向代理配置
location /ws/
{
proxy_pass http://192.168.1.101:6688/; # websocket服务器 不用管ws:// 根据自己的实际情况进行调整(这一步必须有)
proxy_http_version 1.1; # 代理http协议的版本,因为这里是代理websocket协议,所以http协议使用1.1 用于keepalive连接 也就是保持长连接(这一步必须有)
proxy_set_header Upgrade "websocket"; # 表示要“升级”成websocket协议(这一步必须有)
# proxy_set_header Upgrade $http_upgrade; 这个和上面的proxy_set_header Upgrade "websocket";是一个意思,两个写其中一个即可
proxy_set_header Connection "Upgrade"; # 表示要求协议“升级”,也就是说这不是一个普通的http协议
# proxy_set_header X-real-ip $remote_addr; # 这个没啥好解释的(这一步可以没有)
# proxy_set_header X-Forwarded-For $remote_addr;# 标记通过http代理或负载均衡方式连接到web服务器的客户端最原始的ip地址的http请求头字段(这一步可以没有)
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
}
location ~ .*\.(js|css)?$
{
expires 12h;
}
location ~ /.well-known {
allow all;
}
location ~ /\.
{
deny all;
}
access_log /home/wwwlogs/access.log;
}以上就完成了一个最简单最普通的nginx反向代理websocket协议的配置,使用如下(这里以javascript代码举例)
没有使用nginx反向代理之前,我们使用websocket协议需要这么连接,直接写ip+端口
var ws = new WebSocket("ws://192.168.1.101:6688");
使用了nginx反向代理之后:
var ws = new WebSocket("ws://test.css3er.com/ws/");
好处:假如说我们开发有测试服务器和线上正式服务器,项目在测试服和正式服之间的websocket的连接地址依然是ws://test.css3er.com/ws 如果没有使用nginx反向代理,那我们客户端的websocket连接地址在测试服的时候只能写测试服的ip+端口,项目上线的时候就要换成正式服的ip+端口。。很麻烦。。支持跨域版:
server
{
listen 80;
server_name test.css3er.com;
index index.html index.htm index.php;
root /home/wwwroot/default;
autoindex on;
autoindex_exact_size on;
autoindex_localtime on;
# 允许跨域相关配置
add_header Access-Control-Allow-Origin *; # 允许跨域请求的域, *代表所有
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS'; # 允许请求的方法,如 GET/POST/OPTIONS
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization'; # 允许请求的header
# 给OPTIONS添加204的返回,是为了处理在发送POST请求时nginx依然拒绝访问的错误 发送"预检请求"时,需要用到方法OPTIONS,所以服务器需要允许该方法
if ($request_method = 'OPTIONS') {
return 204;
}
#error_page 404 /404.html;
# Deny access to PHP files in specific directory
#location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ { deny all; }
include enable-php.conf;
location /nginx_status
{
stub_status on;
access_log off;
}
# 添加websocket的反向代理配置
location /ws/
{
proxy_pass http://192.168.1.101:6688/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
}
location ~ .*\.(js|css)?$
{
expires 12h;
}
location ~ /.well-known {
allow all;
}
location ~ /\.
{
deny all;
}
access_log /home/wwwlogs/access.log;
}nginx配置了反向代理,会有几个关于超时或连接关闭的选项配置需要注意下:
proxy_connect_timeout #与代理服务器建立连接时的超时时间。 proxy_read_timeout #从代理服务器读取响应的超时时间,也就是在配置的时间内,代理服务器没有响应的话,则断开连接。 proxy_send_timeout #代理服务器数据回传时间,就是在规定时间之内代理服务器必须传完所有的数据。 #以上几个配置选项的配置上下文都可以在http,server,location段内进行配置,同时,这个几个选项的默认时间都是60s(秒)
注意:我这里配置的反向代理websocket协议都是ws://(80端口),如果要配置成ssl,即wss:// 也很简单 和配置https差不多 就是一个证书的事,这里就不上demo了
默认情况下,Websocket的ws协议使用80端口。运行在TLS之上的时候,wss协议默认使用443端口。其实说白了,wss就是ws基于SSL 的安全传输,与https一样样的道理。
如果你的网站是https协议的,那你websocket连接的时候就不能使用 ws://了,浏览器会block掉连接,和https下不允许http请求一样。
websocket和http协议的相关概念补充
WebSocket和HTTP协议不同,但是WebSocket中的握手和HTTP中的握手兼容,它使用HTTP中的Upgrade协议头将连接从HTTP升级到WebSocket。这使得WebSocket程序可以更容易的使用现已存在的基础设施。例如,WebSocket可以使用标准的HTTP端口 80 和 443,因此,现存的防火墙规则也同样适用。
当客户端发过来一个Connection: Upgrade请求头时,nginx是不知道的,所以,当nginx代理服务器拦截到一个客户端发来的 Upgrade请求时,需要显式来设置Connection 、Upgrade 头信息,并使用 101(交换协议)返回响应,在客户端和代理服务器、后端服务器之间建立隧道来支持WebSocket。
当然,还需要注意一下,WebSocket仍然受到nginx缺省为60秒的proxy_read_timeout的影响。这意味着,如果你有一个程序使用了 WebSocket,但又可能超过60秒不发送任何数据的话,那你要么需要增加超时时间,你可以使用proxy_read_timeout指令来增加此超时时间 。或者,每过几秒钟就让代理服务器使用websocket协议发送一个ping的消息给后端服务器,以保持他们之间的联系。使用ping的解决方法有额外的好处,可以发现连接是否被意外关闭。
更具体文档详见nginx官方文档:http://nginx.org/en/docs/http/websocket.html
nginx配置websocket协议的反向代理
nginx通过在客户端和后端服务器之间建立起一条隧道来支持websocket。为了使nginx可以将来自客户端的Upgrade请求转发给后端服务器,Upgrade和Connection的头信息必须被显式的设置。如下所示:
location /ws/ {
proxy_pass http://wsbackend; # 这里请根据自己的实际情况进行填写
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}一旦完成以上设置,nginx就可以处理websocket连接了。
尾声:
本篇博文主要说一下在nginx中如何使用反向代理来代理WebSocket协议,并补充了一些websocket和http协议的一些基本区别。以及配合nginx使用域名方式建立连接,不使用 ip地址 + 端口号 连接 WebSocket,因为这种方式不够优雅,并且多个服务器之间进行切换的时候,客户端连接服务器时,需要改对应服务器的ip地址+端口号。
声明:禁止任何非法用途使用,凡因违规使用而引起的任何法律纠纷,本站概不负责。


精彩评论