【问题标题】:How to resolve a Socket.io 404 (Not Found) error?如何解决 Socket.io 404(未找到)错误?
【发布时间】: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?

标签: node.js express socket.io


【解决方案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"````
    猜你喜欢
    • 2018-12-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-08
    • 2017-02-25
    • 1970-01-01
    • 2017-09-27
    • 2013-11-06
    • 1970-01-01
    相关资源
    最近更新 更多