我正在将Nginx反向代理设置为包含托管其他NodeJs应用程序的服务器上包含Socket.IO的NodeJS应用程序。
NodeJS通过PM2在端口3001上运行。这是Nginx配置:
server {
listen 80;
server_name iptv-staging.northpoint.org;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://localhost:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
通过服务器的IP地址直接http://xxx.xxx.xxx.xxx:3001/
运行应用程序时,所有程序运行都没有问题。来自Socket.IO的Ping / Pong请求大约为50ms(默认pingTimeout为5000ms)。通过其DNS名称http://iptv-staging.northpoint.org
访问该应用程序时,客户端会报告ping超时并断开连接。它将在第一次尝试时重新连接,然后在第一个ping / pong请求中再次断开连接。
据我所知,问题必须与Ngnix反向代理以及Websocket的路由方式有关。似乎服务器对ping请求的答复并未传递给客户端。但我似乎无法确定原因。非常感谢您的帮助。
答案 0 :(得分:0)
我有完全一样的问题。一个工作的人提供了答案,说实话,我并没有完全理解,所以对我没有任何信誉,但是我希望我可以从我的代码中挑出来答案。
首先,我在返回URI信息的服务器上创建了一个API端点。这是告诉客户端使用哪个地址进行连接的关键。
apiRoutes.get('/options', (req, res) => {
Log.info('Received request for app options.');
// This isn't applicable to you, just showing where options declared.
let options = JSON.parse(JSON.stringify(config.get('healthcheck.options')));
// Decide what port to use. It might be a port for a dev instance or from Env
if ((process.env.PORT !== options.port) && (process.env.PORT > 0)) {
options.port = process.env.PORT;
}
// This is the important bit...
var internalUri = req.originalUrl;
var externalUri = req.get('X-Real-URI') || internalUri;
options.basePath = externalUri.substr(0, externalUri.length - internalUri.length + 1);
res.status(200).send(JSON.stringify(options));
});
我的客户是一个React应用,您会考虑如何实现,但这就是我的实现方式。
这是我的“帮助”功能,用于调用“选项”服务...
export async function getOptions() {
const res = await axios.get('/api/options');
return res.data;
}
在我的React页面中,当页面加载时,我将其称为...
componentDidMount() {
getOptions()
.then((res) => {
this.setState({ port: res.port });
// Call a client-side function to build URL. Incl later.
const socketUrl = getSocketUrl(res.port);
console.log(`Attempting to connect to sockets at ${socketUrl}.`);
// This is where it all comes together...
const socket = io(socketUrl, { path: `${res.basePath}socket.io` });
socket.on('connect', function () { console.log(`Connected to ${socketUrl}`); });
socket.on('message', (result) => {
console.log(result);
});
socket.on('data', (result) => {
console.log(`Receiving next batch of results.`);
const filteredResults = JSON.parse(result));
// Do something with the results here...
});
});
.....
最后,getSocketUrl函数...
function getSocketUrl(port) {
console.log(`${window.location.hostname}`);
if (window.location.hostname.toString().includes('local')) {
return `localhost:${port}`;
}
return `${window.location.hostname}`;
}