如何配置Nginx作为WebSocket的反向代理
WebSocket 是一种协议,它提供了一种创建支持客户端和服务器之间实时双向通信的 Web 应用程序的方法。WebSocket 使开发此类应用程序变得更加容易。大多数 现代浏览器 都支持 WebSocket,包括 Firefox、Internet Explorer、Chrome、Safari 和 Opera 等,越来越多的服务器应用程序框架也开始支持 WebSocket。
对于生产环境,为了获得良好的性能和网站或应用程序的高可用性,需要一个理解 WebSocket 协议的负载均衡层,NGINX 从 1.3 版本开始支持 WebSocket,并可以作为反向代理来执行应用程序的负载均衡。
NGINX 通过允许在客户端和后端服务器之间建立隧道来支持 WebSocket。NGINX 将客户端的 Upgrade 请求发送到后端服务器,必须显式设置 Upgrade 和 Connection 头。
location /wsapp/ { proxy_pass http://wsbackend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }
完成此操作后,NGINX 将其视为 WebSocket 连接。
NGINX WebSocket安装及示例
这是一个演示 NGINX 作为 WebSocket 代理工作的实时示例。此示例有助于基于 Node.js 构建的 WebSocket 实现。NGINX 充当使用 ws 和 Node.js 的简单 WebSocket 应用程序的反向代理。这些说明已在 Ubuntu 13.10 和 CentOS 6.5 上进行了测试,但需要针对其他操作系统和版本进行调整。在此示例中,WebSocket 服务器的 IP 地址为 192.168.1.1,NGINX 服务器的 IP 地址为 192.168.1.2
如果尚未安装 Node.js 和 npm,请运行以下命令:
# sudo yum install nodejs npm
Node.js 在 Ubuntu 上安装为 nodejs,在 CentOS 上安装为 node。此示例使用 node,因此在 Ubuntu 上,我们需要创建一个从 nodejs 到 node 的符号链接。
# ln -s /usr/bin/nodejs /usr/local/bin/node
要安装 WebSocket,请运行以下命令:
# sudo npm install ws
注意:如果收到类似“Error: failed to fetch from registry: ws”的错误消息,请运行以下命令来解决问题:
# sudo npm config set registry http://registry.npmjs.org/
然后再次运行**sudo npm install**命令。
# sudo npm install ws
‘ws’ 带有程序 /root/node_modules/ws/bin/wscat,可用于我们的客户端,但我们需要创建一个程序作为服务器。创建一个名为 server.js 的文件,其中包含以下内容:
console.log("Server started"); var Msg = ''; var WebSocketServer = require('ws').Server , wss = new WebSocketServer({port: 8010}); wss.on('connection', function(ws) { ws.on('message', function(message) { console.log('Received from client: %s', message); ws.send('Server received from client: ' + message); }); });
要执行服务器程序,请运行以下命令:
# node server.js
服务器打印初始“服务器已启动”消息,然后侦听端口 8010,等待客户端连接。当它收到客户端请求时,它会将其回显并向客户端发送包含它收到的消息的消息。为了让 NGINX 代理这些请求,我们创建以下配置:
http { map $http_upgrade $connection_upgrade { default upgrade; '' close; } upstream websocket { server 192.168.1.1:8010; } server { listen 8020; location / { proxy_pass http://websocket; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; } } }
NGINX 侦听端口 8020 并将请求代理到后端 WebSocket 服务器。proxy_set_header 指令使 NGINX 能够正确处理 WebSocket 协议。
要测试服务器,我们在客户端系统中运行 wscat:
# /root/node_modules/ws/bin/wscat --connect ws://192.168.1.2:8020
wscat 通过 NGINX 代理连接到 WebSocket 服务器。当您键入要发送到服务器的 wscat 消息时,您会看到它在服务器上回显,然后客户端上会出现来自服务器的消息。这是一个示例交互:
服务器:客户端
# node server.js Server started # wscat –connect ws://192.168.1.2:8020 Connected (press CTRL+C to quit) > Hello Received from client: Hello < Server received from client: Hello
在这里,我们看到客户端和服务器能够通过充当代理服务器的 NGINX 进行通信,并且可以继续发送消息,直到客户端或服务器断开连接为止。所有需要做的就是正确配置 NGINX 以处理 WebSocket,并正确设置标头以处理将连接从 HTTP 升级到 WebSocket 的 Upgrade 请求。