Как передать переменную http-сервера между уровнями и не использовать ее как инструкцию require в другом файле в node.js?

Я создал приложение 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'));
    }
});

Теперь мне нужно передать этот сервер в какой-то файл, а мое приложение построено следующим образом:

server.js 
 app.js
  routes.js
   action.js

Итак, я сделал это быстро, как показано ниже: Есть ли лучший способ сделать это?

Это 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'));
    }
});

В app.js у меня есть файл маршрутизатора, и мне понравилось следующее:

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

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

module.exports = app;

Этот код я помещаю в файл router.js:

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

И в действии js я сделал следующее:

module.exports = {
    setServer: function(http) {
...

Мне нужно передать http между слоями и не использовать его, как требуется, в другом файле/модуле. Как это сделать в node.js?

Ответы

Ответ 1

Если я получу вас правильно, все, что вы хотите сделать, это передать экземпляр другим модулям, не требуя или повторно инициализируя их.

server.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);
    });
}());

router.js

module.exports = function (server) {
    // use server here..
};

action.js

module.exports = function (server) {
    // use server here..
};

Итак, что вы делаете, сначала объявите и инициализируйте объект в своем основном модуле, который вы хотите пройти. Затем во вторичных модулях вы просто объявляете модуль с сигнатурой, которая принимает этот объект в качестве аргумента. Наконец, вы будете требовать их только один раз в своем основном модуле (server.js в этом случае).

Примечание 1: я переименовал переменную http в server, чтобы предотвратить путаницу с встроенным модулем http.

Примечание 2. Не забудьте потребовать эти модули после полной инициализации объекта. например если это HTTP-сервер, как в вашем примере, вам следует лучше потребовать другие модули после создания сервера и в обратном вызове listen.

Примечание 3: ваш код; после изменений, выглядит неправильно. Вы вызываете var server = http.createServer(), затем вы вызываете server.createServer() снова.

Ответ 2

Вам не нужно передавать серверу на маршруты. Просто добавьте их до создания сервера:

someroute.js

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

module.exports = router;

server.js

var app = express();
....
var someroute = require("./routes/someroute");
app.use("/someroute", someroute);
server.createServer(app);

Обновить ответ на основе обратной связи:

В вашем файле server.js у вас, вероятно, есть переменная для хранения экземпляра socket.io при его инициализации, позвоните ему io.

Вы инициализируете переменную io следующим образом:

//example taken from socket.io front page
var io = require('socket.io')(80); 

При регистрации промежуточного программного обеспечения вы можете прикрепить эту переменную к req и использовать ее в маршрутах:

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

В маршрутах вы будете ссылаться на req.io как на экземпляр сокета:

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