如何将Nginx配置为WebSocket的反向代理

WebSocket是一种协议,提供了一种创建Web应用程序的方式,该应用程序支持客户端和服务器之间的实时双向通信。WebSocket使开发这些类型的应用程序变得更加容易。大多数现代浏览器都支持WebSocket,包括Firefox,Internet Explorer,Chrome,Safari和Opera,并且现在越来越多的服务器应用程序框架也支持WebSocket。

在生产环境中,需要多个WebSocket服务器来获得良好的性能和网站或应用程序的高可用性,需要了解WebSocket协议的负载平衡层,NGINX支持使用NGINX版本1.3中的WebSocket并可以采取行动作为进行应用程序负载平衡的反向代理。

NGINX通过允许在客户端和后端服务器之间建立隧道来支持WebSocket。NGINX将把升级请求从客户端发送到后端服务器,必须明确设置升级和连接头。

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安装。该示例使用节点,因此在Ubuntu上,我们需要创建一个从nodejs到node的符号链接:

# ln -s /usr/bin/nodejs /usr/local/bin/node

要安装Websocket,请运行以下命令:

# sudo npm install ws

注意:如果收到错误消息,例如:“错误:无法从注册表获取: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请求。