在这篇文章中,我们将讨论如何将 NGINX 和 NGINX Plus 与 Node.js 和 Socket.IO 结合使用。 我们关于使用 WebSocket 和 NGINX 构建实时 Web应用的帖子非常受欢迎,因此在这篇文章中我们将继续提供使用 Socket.IO 的文档和最佳实践。
Socket.IO 是一个 WebSocket API,随着 Node.js应用的兴起而变得非常流行。 该 API 之所以广为人知,是因为它使构建实时应用程序(如在线游戏或聊天)变得简单。 NGINX 1.3.13 及更高版本和所有 NGINX Plus 版本都支持 WebSocket 连接的代理,这使您可以使用 Socket.IO。 WebSocket 协议允许通过单个 TCP 连接进行全双工或双向通信。
生产中运行的应用s通常需要在端口 80(HTTP)、端口 443(HTTPS)或两者上运行。 如果您的应用的多个组件与用户交互或者您使用端口 80 上的 Web 服务器来传递其他资产,那么这可能是一个挑战。 这使得代理到 Socket.IO 服务器成为必要,而 NGINX 是实现此目的的最佳方式。 无论您有一个后端应用实例还是数百个实例,NGINX 都可以在使用多个节点时对上游进行负载平衡。
要安装 Node.js,请下载适当的发行版(或使用包管理器安装)。 运行npm
install
socket.io
命令安装Socket.IO。
对于此示例,我们假设您的实时应用程序的 Socket.IO 服务器在端口 5000 上运行。 以下是server.js节点应用文件的模板;它是一个充当服务器的基本程序,将传入的请求路由到运行 Socket.IO 服务器的正确端口。
var io = require('socket.io').listen(5000);
io.sockets.on('connection', function (socket) {
socket.on('设置昵称', function (name) {
socket.set('昵称', name, function () {
socket.emit('ready');
});
});
socket.on('msg', function () {
socket.get('昵称', function (err, name) {
console.log('聊天消息来自 ', name);
});
});
});
将如下 JavaScript 代码添加到发送给客户端的文件中,例如index.html 。 此示例请求连接到您的应用以便与用户的浏览器创建 WebSocket。
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io(); // 您的初始化代码在此。
</script>
如果您的应用有多个实例,NGINX 和 NGINX Plus 可以进行负载平衡并将用户会话分发到多个节点。 在 NGINX 或 NGINX Plus 配置中的http
上下文中,包含一个上游
块来定义上游组中的节点。
如下例所示,您可以在服务器
指令中包含权重
参数来设置定向到它的流量比例。 这里srv1.app.com接收的会话比其他服务器多五倍。 NGINX Plus 通过增强负载均衡方法以及添加会话持久性、健康检查、扩展状态报告和负载均衡服务器组的动态重新配置来扩展 NGINX 的反向代理功能。
# 在 http{} 配置块中
上游 socket_nodes {
ip_hash;
服务器 srv1.app.com:5000 weight=5;
服务器 srv2.app.com:5000;
服务器 srv3.app.com:5000;
服务器 srv4.app.com:5000;
}
现在已经声明了上游服务器组,需要配置虚拟服务器来将流量引导到它。 至少,包含proxy_pass
指令并命名上游组。 因为 WebSocket 协议使用 HTTP/1.1 中引入的Upgrade
标头,所以我们包含了proxy_http_version
指令。
服务器 {
server_name app.domain.com;
location / {
proxy_set_header 升级 $http_upgrade;
proxy_set_header 连接“升级”;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header 主机 $host;
proxy_pass http://socket_nodes;
}
}
为了传递静态资产,您可以让 NGINX 代理请求上游 Node.js 实例,但在大多数情况下,让 NGINX 直接为它们提供服务效率更高。
结合上面服务器
块中的server_name
指令,以下位置
块告诉 NGINX 通过从本地/path/to/assets目录提供服务来响应客户端对http://app.domain.com/assets/中内容的请求。 您可以进一步优化静态文件处理或设置满足您需求的缓存过期设置。
位置 /assets {
别名 /path/to/assets;
access_log off;
最大有效期;
}
如果您收到以下错误,则您可能正在运行 1.3 之前的 NGINX 版本。 NGINX 1.3.13 及更高版本支持使用 WebSocket。
WebSocket 连接‘...’失败: WebSocket 握手期间出错: “连接”标头值不是“升级”:keep-alive socket.io.js:2371
“这篇博文可能引用了不再可用和/或不再支持的产品。 有关 F5 NGINX 产品和解决方案的最新信息,请探索我们的NGINX 产品系列。 NGINX 现在是 F5 的一部分。 所有之前的 NGINX.com 链接都将重定向至 F5.com 上的类似 NGINX 内容。”