【发布时间】:2017-07-29 02:44:29
【问题描述】:
有人提出了类似的问题,但我无法正确实施。
我编写了一些节点 js 应用程序,它们在同一 IP 上托管的不同端口上运行。但是,这些端口在一些公共网络上被阻止,例如大学访客 wifi 等。我想知道我是否可以正确设置 NginX(可能具有 websocket 支持)以绕过这些网络上被阻止的端口。具体来说,我想知道是否可以将端口 80(未被阻止)上的访问传递到 localhost 后端的相应端口。此外,我不确定这是否是解决此问题的正确方法。请随时向我推荐替代方案。
例如,假设在服务器端我们有这两个应用程序:
// In app1.js (server side)
var express = require('express');
var app = express();
const server = app.listen(3000,function(){DoSomething();};
const io = require('socket.io')(server);
io.on('connection',function(socket){DoStuff();};
和第二个应用程序:
// In app2.js (server side)
var express = require('express');
var app = express();
const server = app.listen(3001,function(){DoSomething();};
const io = require('socket.io')(server);
io.on('connection',function(socket){DoStuff();};
及其客户端代码
var socket = io.connect('http://mysite.domain.edu:3000'); // works, but not on public wifi
// var socket = io.connect(); // does not work
// var socket = io.connect('http://mysite.domain.edu'); // does not work
// var socket = io.connect('http://mysite.domain.edu/app1'); // does not work
以及第二个应用的客户端:
var socket = io.connect('http://mysite.domain.edu:3001');
这些应用程序单独运行。 NginX 将请求传递到这些端口
# In /etc/nginx/conf.d/mysites.conf
# I am not sure about these lines, but they do not have any effect.
# map $http_connection $upgrade_requested {
# default upgrade;
# '' close;
# }
server {
listen 80;
server_name mysite.domain.edu;
root /home/user/mysite;
location / {
index /index.html;
}
# ap1 on port 3000
location /app1 {
rewrite ^/app1//(.*) /$1 break;
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
# I am not sure I need these.
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-NginX-Proxy true;
# proxy_redirect off;
}
# app2 on port 3001
location /app2 {
rewrite ^/app2//(.*) /$1 break;
proxy_pass http://localhost:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
# I am not sure I need these.
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-NginX-Proxy true;
# proxy_redirect off;
}
}
/etc/nginx/conf.d/mysites.conf 是我唯一的 nginx 配置文件。使用这些配置,在端口 3000 和 3001 被阻止的网络上,我从 io.on('connect_error') 得到 xhr poll error。此外,如果取消注释上述配置文件中的行,我会从io.on('connect_error') 得到timeout 错误。
我不确定我是否正确使用了 websocket。另外我想我在客户端调用io.connect('...:port') 时不应该指定端口,但是如果不指定端口,则无法建立连接。如果有人能指出我的错误或任何缺少的配置,我将不胜感激。
【问题讨论】:
-
是的,NGINX 是解决这个问题的正确工具。您可以配置从端口 80 传入的多个请求,以根据路径(每个应用程序的不同顶级路径段)或基于传入主机名(为每个应用程序使用不同的主机名)路由到服务器上的不同端口都指向您的 NGINX 代理的相同 IP 地址)。对于 socket.io 连接,您也可以使用路径或主机,但主机会更容易配置,因为您不必更改客户端。
-
使用 socket.io,客户端代码
var socket = io()将连接回加载网页的主机和端口(根据定义,它始终打开,因为这是网页的来源) .如果这就是您想要做的,那么只需将 URL 完全排除在 socket.io 连接之外,socket.io 库将自动查看window.location并将其连接基于该主机/端口。
标签: node.js nginx websocket socket.io