配置错误 Nginx + ExpressGateway + Express API + Socket.io
Configuration Error Nginx + ExpressGateway + Express API + Socket.io
我在尝试完成这项工作时遇到了很多困难,我有一个支持多个业务领域的微服务架构,现在我想添加一个新的微服务,它将公开一个套接字连接来服务应用程序的一些实时信息。
查看下图:
我会在这里分享一些方面,看看你能不能帮我解决这个配置问题。
我做了一些测试以确定问题是在哪里引起的,我做了一个直接连接到节点 API 的测试(服务器上的 运行ning)而不使用 Nginx 和 ExpressGateway , 检查下面的 Gif 一切正常:
它建立 'polling' 连接,然后升级到我们想要的 Websocket,收到消息,但不建立任何新连接。
这是 API 服务器配置:
constructor() {
this.app = express();
this.initExpress();
this.initExpressMiddleWare();
this.dvConn = new DAO();
this.server = this.start();
this.io = io().attach(this.server, {
path: `${config.BASE_PATH}`,
origins: '*:*',
transports:['polling', 'websocket'],
serveClient: false
});
this.newSocketUsers = [];
this.io.on('connection', (socket) => {
console.log(`a user connected ${socket.id}`);
const user_id = this.decode_id(socket.handshake.query.user_id).toString();
const socket_id = socket.id;
this.registerConnection(socket_id, user_id);
socket.on('disconnect', () => {
console.log(`a user disconnected ${socket.id}`);
const socket_id = socket.id;
this.unRegisteredConnection(socket_id);
});
});
这是 Angular 客户端应用程序的一部分,用于测试:
constructor(private http: HttpClient) {
this.httpClient = http;
this.socket = io('http://dev.server.com:3033', {
query: {
user_id: '988379518723645912'
},
transports: ['polling', 'websocket']
});
this.socket.on('reconnect_attempt', () => {
this.socket.io.opts.transports = ['polling', 'websocket'];
});
}
connect(): void {
this.socket.on('connect', () => {
console.log('Opening Connection');
});
}
现在问题来了,当这个 运行 通过 Nginx 和 ExpressGateway 时,请看下面的 Gif,看看应用程序如何首先记录 502 错误,然后它继续轮询并且从不升级到 WebSocket,使它与发送的每条新消息都会将其记录为新的轮询请求:
我做了功课,我知道 Nginx 需要一些配置,这是我的 Nginx.conf 配置:
server {
listen 443 ssl;
client_max_body_size 12m;
client_body_buffer_size 16k;
server_name dv3.synth5.orcasnet.com api.orcasnet.com;
ssl_certificate /etc/nginx/ssl/certificate.crt;
ssl_certificate_key /etc/nginx/ssl/key.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCMsssssss';
location / {
proxy_temp_file_write_size 64k;
proxy_connect_timeout 10080s;
proxy_send_timeout 10080;
proxy_read_timeout 10080;
proxy_buffer_size 64k;
proxy_buffers 16 32k;
proxy_busy_buffers_size 64k;
proxy_redirect off;
proxy_request_buffering off;
proxy_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://gateway.domain.net:3020;
}
}
最后是ExpressGateway策略配置:
socStg:
apiEndpoints:
- socStg
policies:
- cors:
- log:
- action:
message: ${req.method} ${req.originalUrl} ${req.headers}
- proxy:
- action:
serviceEndpoint: socStg
changeOrigin: true
ws: true
timeout: 120000
如果您能为我解决这个问题,我将不胜感激,在此先感谢。
简单回答 Express-Gateway 不支持套接字连接,我需要直接使用 Nginx 部署 API。现在正在工作。
以下文档包含作为套接字的事件..
https://www.express-gateway.io/docs/plugins/plugin-development/
module.exports = {
version: '1.2.0',
init: function (pluginContext) {
pluginContext.eventBus.on('hot-reload', function ({ type, newConfig }) {
// "type" is gateway or system
// depends on what file was changed
// newConfig - is newly loaded configuration of ExpressGateway
console.log('hot-reload', type, newConfig);
});
pluginContext.eventBus.on('http-ready', function ({ httpServer }) {
console.log('http server is ready', httpServer.address());
// Proxy websockets to localhost:9015
const httpProxy = require('http-proxy')
var proxy = new httpProxy.createProxyServer({
target: {
host: 'localhost',
port: 9015
}
});
httpServer.on('upgrade', (req, socket, head) => {
proxy.ws(req, socket, head);
});
});
pluginContext.eventBus.on('https-ready', function ({ httpsServer }) {
console.log('https server is ready', httpsServer.address());
});
pluginContext.eventBus.on('admin-ready', function ({ adminServer }) {
console.log('admin server is ready', adminServer.address());
});
}
}
我在尝试完成这项工作时遇到了很多困难,我有一个支持多个业务领域的微服务架构,现在我想添加一个新的微服务,它将公开一个套接字连接来服务应用程序的一些实时信息。 查看下图:
我会在这里分享一些方面,看看你能不能帮我解决这个配置问题。
我做了一些测试以确定问题是在哪里引起的,我做了一个直接连接到节点 API 的测试(服务器上的 运行ning)而不使用 Nginx 和 ExpressGateway , 检查下面的 Gif 一切正常:
它建立 'polling' 连接,然后升级到我们想要的 Websocket,收到消息,但不建立任何新连接。
这是 API 服务器配置:
constructor() {
this.app = express();
this.initExpress();
this.initExpressMiddleWare();
this.dvConn = new DAO();
this.server = this.start();
this.io = io().attach(this.server, {
path: `${config.BASE_PATH}`,
origins: '*:*',
transports:['polling', 'websocket'],
serveClient: false
});
this.newSocketUsers = [];
this.io.on('connection', (socket) => {
console.log(`a user connected ${socket.id}`);
const user_id = this.decode_id(socket.handshake.query.user_id).toString();
const socket_id = socket.id;
this.registerConnection(socket_id, user_id);
socket.on('disconnect', () => {
console.log(`a user disconnected ${socket.id}`);
const socket_id = socket.id;
this.unRegisteredConnection(socket_id);
});
});
这是 Angular 客户端应用程序的一部分,用于测试:
constructor(private http: HttpClient) {
this.httpClient = http;
this.socket = io('http://dev.server.com:3033', {
query: {
user_id: '988379518723645912'
},
transports: ['polling', 'websocket']
});
this.socket.on('reconnect_attempt', () => {
this.socket.io.opts.transports = ['polling', 'websocket'];
});
}
connect(): void {
this.socket.on('connect', () => {
console.log('Opening Connection');
});
}
现在问题来了,当这个 运行 通过 Nginx 和 ExpressGateway 时,请看下面的 Gif,看看应用程序如何首先记录 502 错误,然后它继续轮询并且从不升级到 WebSocket,使它与发送的每条新消息都会将其记录为新的轮询请求:
我做了功课,我知道 Nginx 需要一些配置,这是我的 Nginx.conf 配置:
server {
listen 443 ssl;
client_max_body_size 12m;
client_body_buffer_size 16k;
server_name dv3.synth5.orcasnet.com api.orcasnet.com;
ssl_certificate /etc/nginx/ssl/certificate.crt;
ssl_certificate_key /etc/nginx/ssl/key.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCMsssssss';
location / {
proxy_temp_file_write_size 64k;
proxy_connect_timeout 10080s;
proxy_send_timeout 10080;
proxy_read_timeout 10080;
proxy_buffer_size 64k;
proxy_buffers 16 32k;
proxy_busy_buffers_size 64k;
proxy_redirect off;
proxy_request_buffering off;
proxy_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://gateway.domain.net:3020;
}
}
最后是ExpressGateway策略配置:
socStg:
apiEndpoints:
- socStg
policies:
- cors:
- log:
- action:
message: ${req.method} ${req.originalUrl} ${req.headers}
- proxy:
- action:
serviceEndpoint: socStg
changeOrigin: true
ws: true
timeout: 120000
如果您能为我解决这个问题,我将不胜感激,在此先感谢。
简单回答 Express-Gateway 不支持套接字连接,我需要直接使用 Nginx 部署 API。现在正在工作。
以下文档包含作为套接字的事件..
https://www.express-gateway.io/docs/plugins/plugin-development/
module.exports = {
version: '1.2.0',
init: function (pluginContext) {
pluginContext.eventBus.on('hot-reload', function ({ type, newConfig }) {
// "type" is gateway or system
// depends on what file was changed
// newConfig - is newly loaded configuration of ExpressGateway
console.log('hot-reload', type, newConfig);
});
pluginContext.eventBus.on('http-ready', function ({ httpServer }) {
console.log('http server is ready', httpServer.address());
// Proxy websockets to localhost:9015
const httpProxy = require('http-proxy')
var proxy = new httpProxy.createProxyServer({
target: {
host: 'localhost',
port: 9015
}
});
httpServer.on('upgrade', (req, socket, head) => {
proxy.ws(req, socket, head);
});
});
pluginContext.eventBus.on('https-ready', function ({ httpsServer }) {
console.log('https server is ready', httpsServer.address());
});
pluginContext.eventBus.on('admin-ready', function ({ adminServer }) {
console.log('admin server is ready', adminServer.address());
});
}
}