Совместное использование одного порта из нескольких HTTP-процессов node.js

У меня есть корневой сервер, работающий с несколькими проектами node.js. Они должны работать отдельно в своих процессах и каталогах. Рассмотрим эту структуру файла:

/home
+-- /node
    +-- /someProject      | www.some-project.com
    |   +-- index.js
    |   +-- anotherFile.img
    |   +-- ...
    +-- /anotherProject   | www.another-project.com
    |   +-- /stuff
    |   +-- index.js
    |   +-- ...
    +-- /myWebsite        | www.my-website.com
    |   +-- /static
    |   +-- index.js
    |   +-- ...
    +-- ...               | ...

Каждый index.js должен запускаться как отдельный процесс с его cwd, установленным в его родительскую папку (someProject, anotherProject и т.д.).

Подумайте о vhosts. Каждый проект запускает веб-сервер, который слушает его собственный домен. И там проблема. С тех пор может начаться только один script, все они пытаются привязать к порту 80. Я выкопал в API node.js и искал возможное решение: child_process.fork().

К сожалению, это не очень хорошо. Когда я пытаюсь отправить экземпляр сервера в главный процесс (для последующего запроса запроса) или объект, состоящий из request и response, от мастера до хранилища, я получаю ошибки. Это связано с тем, что node.js внутренне пытается преобразовать эти расширенные объекты в строку JSON, а затем переводит его в свою первоначальную форму. Это заставляет все объекты потерять свою ссылку и функциональность.

Подход Seccond child.js

var http = require("http");

var server = http.createServer(function(req, res) {
    // stuff...
});
server.listen(80);

process.send(server); // Nope

Первый подход master.js

var http = require("http"),
    cp = require("child_process");

var child = cp.fork("/home/node/someProject/index.js", [], { env: "/home/node/someProject" });

var router = http.createServer(function(req, res) {
    // domaincheck, etc...
    child.send({ request: req, response: res }); // Nope
});
router.listen(80);

Итак, это тупик. Но эй! node.js предлагает какие-то ручки, которые можно отправлять. Вот пример из документации:

master.js

var server = require('net').createServer();
var child = require('child_process').fork(__dirname + '/child.js');
// Open up the server object and send the handle.
server.listen(1337, function() {
  child.send({ server: true }, server._handle);
});

child.js

process.on('message', function(m, serverHandle) {
  if (serverHandle) {
    var server = require('net').createServer();
    server.listen(serverHandle);
  }
});

Здесь ребенок непосредственно прослушивает мастер-сервер. Таким образом, между ними нет домена. Итак, вот тупик.

Я также подумал о Cluster, но это использует ту же технологию, что и дескриптор, и поэтому имеет те же ограничения.

Итак... есть ли хорошие идеи?

То, что я сейчас делаю, довольно хак-иш. Я сделал пакет под названием distroy. Он связывается с портом 80 и внутренне проксирует все запросы на пути сокетов домена Unix, такие как /tmp/distroy/http/www.example.com, на которых прослушиваются отдельные приложения. Это также (kinda) работает для HTTPS (см. Мой вопрос на SNI). Оставшаяся проблема заключается в том, что исходный IP-адрес потерян, так как теперь он всегда 127.0.0.1. Я думаю, что могу обойти это путем monkeypatching net.Server, чтобы я мог передать IP-адрес, прежде чем открывать соединение.

Ответы

Ответ 1

Лично я просто хочу, чтобы все они прослушивали выделенные порты или, желательно, сокеты, а затем все, что стоит за выделенным маршрутизатором script или nginx. Это самый простой подход ИМО.

Ответ 2

Если вы заинтересованы в решении node.js, зайдите в bouncy, websocket и https-совместимый прокси-сервер/маршрутизатор маршрутизатора http в node. JS.

Определите ваши маршруты .json как

 {
      "beep.example.com" : 8000,
      "boop.example.com" : 8001
 }

а затем запустите bouncy, используя

 bouncy routes.json 80

Ответ 3

Для подключения промежуточного программного обеспечения существует vhost расширение. Возможно, вы могли бы скопировать некоторые из своих концепций.