如何配置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 请求。

更新于:2023年11月2日

41K+ 次浏览

开启您的职业生涯

完成课程获得认证

开始学习
广告