节点 Nodejs Express Socket.io "等待本地主机" "未发送任何数据"

3

我不理解为什么我的连接会等待本地主机,最终超时。我已经反复阅读了代码很多次,现在我陷入了困境。请帮忙。它说它正在监听端口。

另外,我已经删除了一些代码,但是你可以看到我需要让我的 sockets、express 和 http 运行在同一个端口上。提前谢谢你!

    var express = require("express");
var server = require ("http").createServer(app)
var io = require("socket.io")(server);
var mongo = require("mongodb").MongoClient;
var bodyParser = require("body-parser");
var methodOverride = require('method-override');
var logger = require('morgan');
var serveStatic = require('serve-static');
var errorhandler = require('errorhandler');
var path = require('path');

var app = express();

app.set('port', process.env.PORT || 8080);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(methodOverride());
app.use(require('stylus').middleware(path.join(__dirname, 'public')));
app.use(serveStatic(path.join(__dirname, 'public')));

if (process.env.NODE_ENV === 'development') {
 app.use(errorHandler());
}

app.get("/", function(req, res) {
    res.send("index")
});

io.on("connection", function(socket) {
    console.log("a user connected..");

    mongo.connect(MONGOLAB_URI, function(err, db) {
        if(err) {
        console.log("error connecting to mongo db")
        } else {
            var collection = db.collection("chat messages")
            var stream = collection.find().sort().limit(10).stream();
            stream.on("data", function(chat) {
                console.log("emitting chat");
                socket.emit("chat", chat.content);
            });
        }
    });

    socket.on("disconnect", function() {
        console.log("user disconnected");
    });

 socket.on("chat", function (msg) {
        mongo.connect(MONGOLAB_URI, function(err, db) {
            if(err) {
        console.log("error");
            } else {
                var collection = db.collection("chat messages");
                collection.insert({content: msg}, function(err, doc) {
                    if (err) {
                        console.log("error insterting msg to database")
                    } else {
                        console.log("inserted " + msg + "to db - content")
                    }
                }); 
            }
        });
        socket.broadcast.emit("chat", msg);
    }); 
});

server.listen(app.get("port"), function (err, data) {
    if (err) {
        console.log(err)
    };
    console.log("listening on " + app.get("port"));
});
2个回答

1

哇!!我解决了!我的代码本质上没有什么问题(虽然异步Mongo肯定是更好的实践),除了我引用express的方式。我的代码是var express = require("express");,然后我会这样设置一个app变量:var app = express()。那种方法已经过时了,不再起作用。使用express和设置app变量的正确方法是:"var app = require(" express ")();" 这个微小的变化让我的服务器正常工作了。非常感谢你的帮助,并向我指出了更好、异步使用mongo的方法。我太开心了!哈哈编辑:看来问题不是过时的方法,而是我定义app变量的顺序有问题。在定义之前就要求“app”。


1
var express = require("express"); var app = express(); 和 var app = require("express")(); 实际上是一样的,只不过你将 express 工厂方法存储到变量 express 中... 除此之外,你肯定还改了其他东西。 - Patrick Roberts
1
这就是我所相信的。但是在查看了socket.io网站上的示例后,我绝对只更改了一件事,那就是应用程序变量的设置方式和express的要求。这非常奇怪...或者可能是我的应用程序变量现在被调用的位置。在我需要express、socket.io和所有中间件之前设置一个应用程序变量(如我最初的问题所示)。在这里,我将我的应用程序变量设置在第一行,并在其中引入了express。这是唯一的其他更改...但这对我来说不太合理。 - itsreallyike

0

你的listen()似乎有点问题,我没有看到server.listen()中带有err和data参数的回调API。从外观上看,回调函数中没有任何参数。只需将其设置为空的匿名函数,你确定没有遇到其他错误吗?

--编辑发现你的mongodb集合存在问题,你正在使用同步而不是异步的集合方法,有可能导致集合未定义。请改为以下方式:

socket.on("chat", function(msg) {
    mongo.connect(MONGOLAB_URI, function(err, db) {
        if (err) {
            console.log("error");
        }
        //don't do spaces in collection names - make it async with callback
        db.collection("chatmessages", function(err, col) {
            if (err) {
                console.log(err)
                return;
            }
            col.insert({ content: msg}, function(err, doc) {
                if (err) {
                    console.log("error insterting msg to database")
                    return;
                }
                console.log("inserted " + msg + "to db - content")
            });
        });
    });
});

--以下编辑

var http = require('http');
var express = require('express');
var mongodb = require('mongodb');
//other stuff

var app = express();

//do all your app.use() here


//add all your routes here.
//so if routes where in a different file theortically
//you would have requires them in at the top like var routes = require('./routes');
//and here you would do app.use(routes);

var server = http.createServer(app);

//now you can require your io here

var io = require('socket.io')(server) //because server is now filled with all the configuration

//do you io events down below..

基本上,当你使用 var app = require('express')(); 时, 它会执行与下面代码相同的操作: var express = require('express'); var app = express(); 你只是将这些调用链接在一起,而不是过时或新的。


很遗憾,那并没有起作用。我已经编辑了我的代码,以便它显示所有内容。 - itsreallyike
你的意思是,我应该将 server.listen 放置在 io.on 的作用域内,在 server.on("disconnect") 行之前吗? - itsreallyike
如果你在控制台看到了'listening on port #'的输出,那么服务器已经成功启动监听了.. 它可能会在集合不是异步的时候卡住(我猜)。 - Andrei
谢谢!我已经做出了更改,我肯定认为它们更有意义。然而,它仍然无法加载。 :-( - itsreallyike
1
除了TypeScript之外,另一个建议是优先使用ES6声明而不是ES5。var将变量定义提升到作用域的顶部,因此在实际声明和定义变量之前使用变量不会引发错误。另一方面,ES6 let不会提升,因此如果您尝试在定义之前使用变量,它将引发错误,这正是应该发生的。对于这些类型的错误,不需要使用TypeScript,只需使用node版本4.x或更高版本即可。 - Patrick Roberts
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接