我有一个带有 Express 和 Socket.io (Ubuntu 18.04) 的 Nodejs 服务器应用程序。在 nGinx (1.14) 反向代理进入场景之前,它一直运行良好。 nginx 服务器运行在不同的 Node.js 应用程序机器上,每个应用程序在它自己的虚拟机上,在同一个网络内。
2.1.1 版的服务器和客户端。
nginx 服务器负责多个应用程序重定向。
我尝试了几种配置组合,但没有任何效果。
这是我尝试过的(“company1”的示例):
/etc/nginx/conf.d 中的 default.conf
location /company1-srv/ {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-NginX-Proxy true;
proxy_redirect off;
proxy_pass http://172.16.0.25:51001/;
}
然后在客户端代码中,我使用“路径”选项进行连接,因为 socket.io 错放了它的库路径。
// companySrv and URL is actually returned by another service (following code is for illustrative purposes):
let companyUrl = 'https://api.myserver.com/company1-srv';
let companySrv = '/company1-srv';
socket(companyUrl, {
path: companySrv + '/socket.io/'
});
我还尝试删除路径选项并为 socket.io 内容配置了特定的 /location(用于测试目的):
location /socket.io/ {
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;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-NginX-Proxy true;
proxy_redirect off;
proxy_pass http://172.16.0.25:51001/socket.io/;
}
没有任何效果。
它连接,但不发射任何东西。不久(一分钟左右)后,它变得不可用,引发“断开连接”(原因:传输关闭)客户端事件。
服务器:
const io = require('socket.io')(https || http, {
transports: ['polling', 'websocket'],
allowUpgrades: true,
pingInterval: 60000*60*24,
pingTimeout: 60000*60*24
});
我还尝试编辑 nginx.conf 并编写“上游 socket_nodes { ...”并使用 proxy_pass http://socket_nodes。这没有意义,因为我需要根据公司的不同进行确切的重定向,但为了进行测试,我做了,但效果不佳。
我需要做什么?
谢谢
答案 0 :(得分:0)
我们也使用 socket.io
和来自 ngnix
的反向代理。我可以分享一些我们的设置,也许这有助于排除问题。
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
}
stream {
log_format basic '$time_iso8601 $remote_addr '
'$protocol $status $bytes_sent $bytes_received '
'$session_time $upstream_addr '
'"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';
access_log /var/log/nginx/stream.log basic;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
##
# Server Blocks
##
# DOMAINEXAMPLE A
server {
server_name exampleA.domain.com;
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://192.168.21.105:5050;
}
}
# DOMAINEXAMPLE B
server {
server_name exampleB.domain.com;
location /api {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://192.168.21.106:5050;
}
}
}
这里最有趣的部分可能是服务器块
# DOMAINEXAMPLE A
server {
server_name exampleA.domain.com;
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://192.168.21.105:5050;
}
}
# DOMAINEXAMPLE B
server {
server_name exampleB.domain.com;
location /api {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://192.168.21.106:5050;
}
}
对于位于 /
的位置 http://192.168.21.105:5050
,我们有一个 NodeJS 进程正在运行,包括 socket.io
的设置
const express = require('express');
const http = require('http');
const app = express();
const server = http.createServer(app);
const io = require('socket.io')(server);
对于位于 /api
的位置 http://192.168.21.106:5050
,我们有另一个 NodeJS 进程正在运行,包括 socket.io
的稍微不同的设置
const express = require('express');
const http = require('http');
const app = express();
const server = http.createServer(app);
const io = require('socket.io')(server, {path: '/api/socket.io'});
在这两种情况下,socket.io 对我们来说都很好
我们在服务器端实际做的是为 socket.io 创建一个命名空间,比如
const io= require('socket.io')(server, {path: '/api/socket.io'});
const nsp = io.of('/api/frontend');
然后在客户端,像这样连接到它
import io from 'socket.io-client'
const socket = io('https://exampleB.domain.com/api/frontend', {path: "/api/socket.io"});