node.js - 使用反向代理 Nginx 的 Socket.io Socket.onPacket 错误
问题描述
我有一个与 node.js 服务器通信的小型 Angular 应用程序。两者都部署在 aws 上,我使用 Nginx 反向代理在端口 4000 访问 node.js 服务器。
nodejs.server 的所有端点都可以正常工作,除了socket.io连接。当我在我的机器中运行这两个应用程序(前端应用程序和 node.js 服务器)时,socket.io 连接工作正常,但是当我尝试在 aws 上部署它时,我在前端应用程序中收到此错误:
Error: server error
at Socket.onPacket (socket.js:401)
at XHR.<anonymous> (socket.js:216)
at XHR.push.dMso.Emitter.emit (index.js:145)
at XHR.onPacket (transport.js:103)
at callback (polling.js:101)
at Array.forEach (<anonymous>)
at XHR.onData (polling.js:105)
at Request.<anonymous> (polling-xhr.js:94)
at Request.push.dMso.Emitter.emit (index.js:145)
at Request.onData (polling-xhr.js:236)
这是我的 Nginx 配置/etc/nginx/sites-available/default
:
server{
charset utf-8;
listen 80 default_server;
server_name 18.231.153.164;
# angular app & front-end files
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
root /opt/front-end/dist/admin;
try_files $uri /index.html;
}
# node api reverse proxy
location /api/ {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://localhost:4000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# node api reverse proxy
location /socket.io {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://localhost:4000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
如您所见,我的 node.js 在端口 4000 上运行,因此每次有人尝试使用路径/api/访问网站时,它都会被重定向到 node.js 服务器。
这是我的一段 node.js 代码:
const socketio = require('socket.io');
const express = require('express');
const app = express();
const port = 4000;
const httpServer = app.listen(port, () => {
console.log('Server listening on port ' + port);
});
let io = socketio(httpServer, {
cors: {
origin: "http://localhost:5200",
},
});
// auth moddleware
io.use((socket, next, err) => {
const jwtToken = socket.handshake.query.jwtToken;
// console.log('token --> ', jwtToken);
const user = socket.handshake.query.user;
if (!user) {return};
socket.user = JSON.parse(user);
next();
});
io.on('connection', (socket) => {
socket.emit('messageFromServer', {data: 'Welcome to server'});
})
这是我的一段前端代码:
import {io} from 'socket.io-client';
...
// Connect to server (When I am running locally I change '/api' to 'http://localhost:4000'
this.socket = io('/api', {secure: true, reconnection: true, rejectUnauthorized: false, query: {user: user, jwtToken: this.authService.authValue.jwtToken}});
// Listen to events
this.socket.on('usersOnline', (usersOnline) => {
console.log('Users online now:', usersOnline);
});
this.socket.on('connect_error', (err) => {
console.log('ERR::', err);
});
服务端socket.io的版本是“^4.0.0”,前面socket.io-client的版本是“^4.0.0”。
我相信这个问题与反向代理和socket.io有关。正如我之前所说,socket.io 连接在本地环境中运行良好。
有人可以帮帮我吗?
解决方案
我找到了解决方案。我需要添加proxy_redirect off;
socket.io 反向代理。
location /socket.io {
proxy_pass http://localhost:4000;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
然后我遇到了另一个问题,在字体端我开始收到错误或无效的命名空间。所以我将客户端连接/
改为 od /api
:
this.socket = io('/', {query: {user: user, jwtToken: this.authService.authValue.jwtToken}});
推荐阅读
- hosting - 网站主机不见了 | 恢复旧网站
- mysql - 创建提取字符串 sql 的新列
- c# - 在 ASP.NET MVC 中使用 C# 推送通知
- c# - HttpWebRequest 在 c# 中返回错误,适用于简单的 php 示例
- python - Tensorflow 对象检测 API:检测到特定类时将 GPIO 引脚设为高电平
- jenkins - Jenkins X 在预览环境中使用机密
- android - 位图分辨率问题
- excel - Excel VBA CustomSort从范围
- android - 短信检索器 api 11 位哈希在 PlayStore 应用程序上不起作用
- testing - 使用另一个测试作为测试构造函数