如何在层之间传递http服务器变量,而不是在node.js中的另一个文件中将其用作require语句?

15 javascript node.js express

我已经创建了一个nodeJS应用程序,它需要创建一个服务器,它在文件server.js中可以正常工作:

http.createServer(app).listen(app.get('port'), function (err) {
    if (err) {
        console.error(err);
    } else {
        runProcess();
        console.log('Server listening on port ' + app.get('port'));
    }
});
Run Code Online (Sandbox Code Playgroud)

现在我需要将此服务器传递给某个文件,我的应用程序构建如下:

server.js 
 app.js
  routes.js
   action.js
Run Code Online (Sandbox Code Playgroud)

所以我像下面那样快速做到了,有没有更好的方法呢?

这是更改后的server.js:

var server = http.createServer(app);
app.setServer(server);
server.createServer(app).listen(app.get('port'), function (err) {
    if (err) {
        console.error(err);
    } else {
        runProcess();
        console.log('Server listening on port ' + app.get('port'));
    }
});
Run Code Online (Sandbox Code Playgroud)

app.js我有路由器文件,我确实喜欢以下内容:

app.use('/', routes.router, function (req, res, next) {
    next();
});

app.setServer = function(http) {
    routes.setServer(http);
}

module.exports = app;
Run Code Online (Sandbox Code Playgroud)

这段代码我放在router.js文件中:

module.exports = {
    router: applicationRouters,
    setServer: function(http) {
        //here I set server to the file action.js
        action.setServer(http);
    }
}
Run Code Online (Sandbox Code Playgroud)

在动作js中,我做了以下事情:

module.exports = {
    setServer: function(http) {
...
Run Code Online (Sandbox Code Playgroud)

我需要在层之间传递http,而不是在不同的文件/模块中使用它.我如何在node.js中做到这一点?

Vse*_*nin 6

您不需要将服务器传递给路由.只需在创建服务器之前包含它们:

someroute.js

var router = require("express").Router();
router.use('/', routes.router, function (req, res) {
    return res.json();
});

module.exports = router;
Run Code Online (Sandbox Code Playgroud)

server.js

var app = express();
....
var someroute = require("./routes/someroute");
app.use("/someroute", someroute);
server.createServer(app);
Run Code Online (Sandbox Code Playgroud)

根据反馈更新答案:

在你的server.js文件中,你可能有一个变量来保存socket.io实例,当它被初始化时,让我们调用它io.

您将初始化io变量,如下所示:

//example taken from socket.io front page
var io = require('socket.io')(80); 
Run Code Online (Sandbox Code Playgroud)

注册中间件时,您可以将此变量附加到req路径中并在路径中使用它:

//this goes prior to your route registration
app.use(function(req, res, next) {
    req.io = io;
});
Run Code Online (Sandbox Code Playgroud)

在路由中,您将引用req.io为套接字实例:

router.use('/', routes.router, function (req, res, next) {
    req.io.emit("something", {});
});
Run Code Online (Sandbox Code Playgroud)


Onu*_*rım 2

如果我的理解正确,您所需要做的就是将一个实例传递给其他模块,而不必要求或重新初始化它们。

服务器.js

module.exports = (function () {
    // create the server
    var http = require('http'),
        express = require('express'),
        app = express(),
        server = http.createServer(app);

    server.listen(80, function () {
        // require and invoke the modules that need this http/server instance here
        require('router')(server);
        require('action')(server);
    });
}());
Run Code Online (Sandbox Code Playgroud)

路由器.js

module.exports = function (server) {
    // use server here..
};
Run Code Online (Sandbox Code Playgroud)

动作.js

module.exports = function (server) {
    // use server here..
};
Run Code Online (Sandbox Code Playgroud)

所以你要做的就是,首先在主模块中声明并初始化你想要传递的对象。然后在辅助模块中,您只需使用将此对象作为参数的签名来声明该模块。最后,您只需在主模块(本例中为 server.js)中需要它们一次。

注 1:我将http变量重命名为,以防止与内置模块 server混淆。http

注意 2:在完全初始化对象后,不要忘记需要这些模块。例如,如果这是一个 http 服务器(如您的示例所示),那么您最好在创建服务器后并在回调中需要其他模块listen

注3:您的代码;更改后,看起来不正确。你打电话var server = http.createServer()然后再打电话server.createServer()