为啥我不断收到 Socket.io 轮询请求的 404 错误?

Posted

技术标签:

【中文标题】为啥我不断收到 Socket.io 轮询请求的 404 错误?【英文标题】:Why do I keep getting 404 error for Socket.io polling requests?为什么我不断收到 Socket.io 轮询请求的 404 错误? 【发布时间】:2021-02-04 23:58:54 【问题描述】:

从我的 React 应用程序中获得很多这样的生成:GET http://exampleenvv2-env.eba-yjtafbmz.us-east-1.elasticbeanstalk.com/socket.io/?EIO=3&transport=polling&t=NLE1Pn5

我的 React 位于 8080 端口,Express 位于 5000 端口,均位于 AWS Beanstalk 上的 nginx 之后。从 SSH 进入实例,看起来两者都运行良好,并且由于我可以在浏览器中正常访问 React 应用程序,因此它看起来可以正确路由到该服务器。

我能够让一个基本的聊天应用程序在两个浏览器窗口之间本地运行。

我在我的 React page.js 中这样做:

import socketIOClient from "socket.io-client";
var io = require('socket.io');
var socket = socketIOClient();

Server.js(用于 Express/Socket.io 监听):

const express = require('express');
const app = express();
const http = require('http').Server(app);
const io = require('socket.io')(http);
const router = express.Router();

var Immutable = require('immutable');
var SortedSet = require("collections/sorted-set");

var Map = Immutable.Map;
var List = Immutable.List;

var hostname = process.env.IP || 'localhost';
var port = 5000;

var games = Map();
var players = Map();
var availableKeys = SortedSet();
var maxKey = 0;

/.../

http.listen(port, hostname, function () 
console.log("Server is listening on http://" + hostname + ":" + port);
);

Nginx 位置配置部分:

location / 
  proxy_http_version  1.1;
  proxy_pass          http://127.0.0.1:8080/;
  proxy_set_header    Host $host;
  proxy_set_header    X-Real-IP $remote_addr;
  proxy_set_header    Connection $connection_upgrade;
  proxy_set_header    Upgrade $http_upgrade;
  proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;


location /socket.io 
  proxy_pass                http://127.0.0.1:5000/;
  proxy_set_header          Host $host;
  proxy_set_header          X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header          X-NginX-Proxy true;
  proxy_set_header          X-Real-IP $remote_addr;
  proxy_ssl_session_reuse   off;
  proxy_cache_bypass        $http_upgrade;

我已经尝试使用路径选项到“/socket.io”作为节点并做出反应,但这似乎没有帮助。

这是error.log 的示例:

2020/10/22 01:36:44 [error] 20352#0: *279 connect() failed (111: Connection refused) while connecting
to upstream, client: 172.31.22.103, server: , request: "GET /socket.io/
EIO=3&transport=polling&t=NLDyuCl HTTP/1.1", upstream: "http://127.0.0.1:5000//? 
EIO=3&transport=polling&t=NLDyuCl", host: "exampleenvv2-env.eba-yjtafbmz.us-east- 
1.elasticbeanstalk.com", referrer: "http://exampleenvv2-env.eba-yjtafbmz.us-east- 
1.elasticbeanstalk.com/"

【问题讨论】:

你在使用任何负载均衡器吗? 由于您使用的是 EB,因此您可以使用不需要 Nginx 的应用程序负载均衡器,它支持 TCP 连接的粘性并且还可以处理升级。还查看 Nginx 似乎您的套接字服务器在端口 5000 上运行 5000 端口是否打开? 困惑:在营销术语上,它说负载均衡器是自带的,听起来像是自动设置的?我已经为侦听器/进程(端口 80)启用了任何默认值,并且 EC2 实例似乎看到了一个活动的实例。我已经为 EB 安全组中的所有流量设置了 5000,netstat 看到节点在 5000 上运行。 另外,我最初还是通过端口 80 汇集所有内容,并让 Nginx 将其拆分为 React 的“/”和后端 nodejs 的“/socket.io”。有点难以调试,5000 或 8080 在 eth0 上没有得到任何东西。 实际上,如果我使用 React,是否需要将 <script src="/socket.io/socket.io.js"></script> 添加到我的 index.html 中? package.json 应该负责编译模块,然后 .js 中的 require() 应该获取该文件? 【参考方案1】:

原来the top-ranked answer here 的 Nginx 配置是我所需要的。

我最终编辑了路径,但还添加了其他几行,但我真的认为路径很挑剔。 Nginx 擅长从特定到通用,但是否需要精确匹配或最接近相关取决于用户。

location ~* \.io 
  proxy_pass                http://127.0.0.1:5000;
  proxy_set_header          Host $http_host;
  proxy_set_header          X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header          X-NginX-Proxy false;
  proxy_set_header          X-Real-IP $remote_addr;
  proxy_ssl_session_reuse   off;
  proxy_set_header          Upgrade $http_upgrade;
  proxy_set_header          Connection "upgrade";
  proxy_redirect            off;
  proxy_http_version        1.1;

感谢其他答案,这是解决此设置问题的其他好步骤!

【讨论】:

【参考方案2】:

我不是nginx 专家,但nginx 是否有可能将您的套接字请求路由到您的反应应用程序?位置路径/ 可能匹配所有请求并将所有流量路由到反应应用程序。尝试摆脱@Biswa 已经评论过的nginx,或者尝试为您的反应应用程序制定更具体的路径,例如/ui 并查看套接字请求是否真正路由到正确的进程。

【讨论】:

你也可以试试这个,从不同的路由提供你的用户界面,或者只是删除 nginx,因为它已经带有负载均衡器

以上是关于为啥我不断收到 Socket.io 轮询请求的 404 错误?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 socket.io 实现长轮询?

socket.io 不断尝试在错误的地址上使用轮询

接收错误:xhr 轮询错误 socket.io 客户端反应

websocket——通信梳理(短轮询、长轮询、socket、websocket、socket.io)

Node中不断轮询MongoDB的效率

Socket.io - 失败:连接在收到握手响应之前关闭