如何解决 Socket.io 404(未找到)错误?

Posted

技术标签:

【中文标题】如何解决 Socket.io 404(未找到)错误?【英文标题】:How to resolve a Socket.io 404 (Not Found) error? 【发布时间】:2015-02-08 05:11:43 【问题描述】:

我正在使用带有 Express 的 Socket.io。在我的项目中,我有一个登录页面和一个主页。当我成功登录时,我导航到 localhost:3000/home 并出现此错误:

GET http://localhost:3000/socket.io/?EIO=3&transport=polling&t=1418187395022-0 404 (Not Found)

我没有对我的app.js(由 express 创建的项目)进行任何修改。

index.js:

var express = require('express');
var router = express.Router();
var http = require('http');
var fs = require('fs');
var io = require('socket.io')(http);
/* GET home page. */
router.get('/', function(req, res) 
  res.render('index',  title: 'Express' );
);

router.get('/home', function(req, res) 
  res.render('home',  title: 'Express' );
);

io.on('connection', function(socket)
    console.log("User Connected");
  socket.on('chat message', function(msg)
    io.emit('chat message', msg);
    console.log("Message");
  );
   socket.on('disconnect', function(msg)
    console.log("User DisConnected");
  );

);

router.post('/authenticate', function(req, res) 
    fs.readFile("./public/Verification/Users.json", "utf8", function (err, data) 
        if (err) 
            console.log(err);
        else
            var result = JSON.parse(data);
            for(var i=0;i<result.Users.length;i++)
                if(req.body.username == result.Users[i].username && req.body.password ==     result.Users[i].password)
                    console.log("Success!!!!!!!!!!!!!!");
                    res.location("home");
                    res.redirect("home");
                
            
        
        );
);

module.exports = router;

在我的layout.jade 中,我这样定义了 Socket.io:

script(src='https://cdn.socket.io/socket.io-1.2.0.js')

【问题讨论】:

您的 express 服务器在哪里配置为侦听端口 3000?我在任何地方都没有看到那部分?而且,它需要在你连接 io 服务器端之前。 默认监听3000,我什么都没配置。 据我所知,端口 3000 上没有默认值。如果 localhost:3000/home 产生错误,那么您的 Web 服务器在端口 3000 上没有正常工作。您运行的是哪个版本的 Express? 【参考方案1】:

如果您运行的是 Express 4,在我看来您缺少代码行:

var app = express();
var server = app.listen(3000);

这将启动您的网络服务器并将其设置为端口 3000。在此处查看简单的 Express 4 应用程序:http://expressjs.com/4x/api.html

然后,要启动 socket.io,您需要添加:

var io = require('socket.io').listen(server);

而且,不需要这行:

var http = require('http');

【讨论】:

是的,我正在使用 express 4。我将此代码放在 app.js 中,它给了我“EADDRINUSE”错误。 是的,工作!我错误地在 index.js 中添加了相同的代码,这就是它给出错误的地方。谢谢。 非常感谢兄弟我也在搞这个 @jfriend00,我和你提到的一样。但我仍然面临这个错误。 @JaynaTanawala - 如果不查看您的具体代码,我们无法帮助您解决问题。请发布一个新问题并显示您的实际代码。【参考方案2】:

因为过去 5 个小时我一直在与这个问题作斗争。这是谷歌的第一个结果。

当然是 2015 年了,部分代码发生了变化。

我认为目前 index.js 代码最好的开始是:

var express = require('express'),
    http = require('http');
var app = express();
var server = http.createServer(app);
var io = require('socket.io').listen(server);

server.listen(3000);

顺序非常重要。

我的问题是,一切都已正确安装并且节点正在侦听。但是 example.com/socket.io/socket.io.js 和 example.com/socket.io/?eio=... 找不到 404。 但是,当我尝试 example.com:3000/socket.io/socket.io.js 时,一切正常。所以现在的问题是,如何将 getJSON 查询更改为具有端口部分。

所以解决方案是编辑 main.js,它被添加到你的聊天所在的 index.html 中。 有:

var socket = io();

替换为

var socket = io.connect('http://example.com:3080');

这更正了 getJSON 查询 URL 并添加了正确的端口,不再是 404。我希望它对未来的人有所帮助。

【讨论】:

所选的解决方案不起作用,但这个解决方案起作用了 :) 谢谢 :) 我还会在此处添加一个问题的注释,即每个人都从这些套接字开始。那些节点不会活着。当您关闭控制台时,它们将消失。为此,您必须安装一个插件,这将使节点保持活动状态。遗憾的是,我已经不记得了,但我认为是大象.io。尽管如此,您还需要一些额外的东西来保持节点处于活动状态。 我尝试查看 nginx conf,并在其中添加了以下行: var socket = io.connect('example.com:3080'); // 这个端口号花了几个小时,因为我只是复制/粘贴它:) 它是 3080,而不是 3000。【参考方案3】:

只需调用服务器的监听,并通过回调将服务器实例传递给模块。

来自 express 应用的 bin/www 文件的一部分

var server = http.createServer(app);
server.listen(port, function () 
  console.log('app listening on *:' + port);
  require('../socket')(server);
  console.log('socket server will be on *:' + port);
);

server.on('error', onError);
server.on('listening', onListening);

这就是我的套接字模块socket.js

var io = ;

module.exports = (server, serveradmin) => 
  io = require('socket.io')(server);
  io.on('connection', function (socket) 
    console.log(socket + ' a user connected');
  );

所有的套接字监听器和发射器都从这里管理。

【讨论】:

【参考方案4】:

这就是我在服务器端解决它的方法(2018 年):

const app = express();
const socketIO = require('socket.io');

const server = express()
  .use(app)
  .listen(PORT, () => console.log(`Listening Socket on $ PORT `));

const io = socketIO(server);

在客户端

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.1/socket.io.js"></script>

看起来很简单,但我花了几个小时才找到解决方案,因为上面的解决方案对我不起作用。

【讨论】:

app = express(); 然后server = express().use(app) 有什么意义?这是故意的还是只是一个错误?【参考方案5】:

请把你的配置改成这个

var express = require('express');

// App setup
var app = express();
var socket = require('socket.io')

var server = app.listen(4000, function()
    console.log('listening for requests on port 4000,');
);

let io = socket(server)
io.on('connection', function(socket)
  console.log(`$socket.id is connected`);
);

【讨论】:

非常感谢,这正是我想要的。【参考方案6】:

对于任何使用 nginx 代理到 node.js 的人来说,问题可能是 nginx conf 而不是 node.js 代码。

您可以使用 GET 请求(使用 curl、Postman 或浏览器)对http://localhost/socket.io/(带有尾部斜杠)和一个对http://localhost:3000/socket.io/ 进行测试

如果http://localhost/socket.io/ 给出 404 not found 或“Cannot GET /”,但http://localhost:3000/socket.io/ 返回如下响应:

"code":0,"message":"Transport unknown"

那么后端 node.js 和 socket.io 都在工作,但是 nginx 没有正确传递请求。

检查它应该看起来像:

location /socket.io/ 
                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://127.0.0.1:3000;

特别注意proxy_pass http://127.0.0.1:3000 末尾没有斜杠,因为我们希望按原样传递原始请求 URI(即包括 /socket.io)。

来自nginx proxy_pass docs:

如果使用 URI 指定 proxy_pass 指令,那么当 请求被传递给服务器,规范化请求 URI 的一部分 匹配位置被指令中指定的 URI 替换:

location /name/ 
    proxy_pass http://127.0.0.1/remote/;  

如果 proxy_pass 没有指定 URI,则请求 URI 以相同的方式传递给服务器 处理原始请求时客户端发送的表单,或 处理更改的 URI 时传递完整的规范化请求 URI:

location /some/path/ 
    proxy_pass http://127.0.0.1; 

https://www.nginx.com/blog/nginx-nodejs-websockets-socketio/ 涵盖了标头要求(本质上,websocket 需要升级标头,它需要 HTTP/1.1)

【讨论】:

我在 AWS 上部署了我的 nodejs 套接字,使用 http,相同的代码可以正常工作,但使用 https(尽管 LB 中有一个活动实例,但引入了负载均衡器),套接字连接不断下降。我对您的步骤进行故障排除,我能够收到此"code":0,"message":"Transport unknown"。 nginx 有什么问题? 我看到这个错误:````````2021/11/13 16:58:58 [error] 21285#21285: *5 connect() failed (111: Connection refused)连接到上游时,客户端:172.31.27.33,服务器:,请求:“GET /socket.io/?EIO=4&transport=polling HTTP/1.1”,上游:“127.0.0.1:8080/socket.io/?EIO=4&transport=polling”,主机:“domain.com”2021 /11/13 17:24:49 [错误] 22100#22100: *2 connect() 在连接到上游时失败(111:连接被拒绝),客户端:172.31.27.33,服务器:,请求:“POST /socket.io /?EIO=4&transport=polling&sid=xLc-Bz_iYKAXXXXXX-HTTP/1.1"````

以上是关于如何解决 Socket.io 404(未找到)错误?的主要内容,如果未能解决你的问题,请参考以下文章

GET/socket io 未找到 404

/socket.io/* 404 未找到烧瓶

获取 http://localhost:3000/socket.io/socket.io.js 404(未找到)

GET http://js:port/socket.io/1/ 404 未找到

Node.js socket.io.js 未找到或 io 未定义

GET http://localhost:8080/socket.io/?EIO=3&transport=polling&t=McNiz_D 404(未找到)