首页 > 解决方案 > 使用反向代理 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 连接在本地环境中运行良好。

有人可以帮帮我吗?

标签: node.jsnginxsocket.iowebserver

解决方案


我找到了解决方案。我需要添加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}});

推荐阅读