2015-09-02 2 views
0

Я пытаюсь, чтобы два разных процесса узла (используя кластер) пытались стать серверами в порт. Однако всякий раз, когда второй процесс попадает в порт, он не обнаруживает, что порт используется.Node.js Процессы Не обнаруживать порт уже используется

Я подозреваю, почему они не обнаруживают, открыт ли порт или нет, из-за характера обратных вызовов (я обнаруживаю, что порт используется или не использует функцию portInUse, поэтому он извлекается асинхронно, и позже может возникнуть некоторый конфликт).

Вот код:

var cluster = require('cluster'); 
var net = require('net'); 

var PORT = 1337; 
var list = {}; 
var portIsBeingUsed = false; 

// Variable that detects if the port is in use. 
var portInUse = function(port, callback) { 
    var server = net.createServer(function(socket) { 
    socket.write('Echo server\r\n'); 
    socket.pipe(socket); 
    }); 

    server.listen(port, 'localhost'); 
    server.on('error', function (e) { 
    callback(true); 
    }); 

    server.on('listening', function (e) { 
    server.close(); 
    callback(false); 
    }); 
}; 

if (cluster.isMaster) { 
    for (var i = 0; i < 2; i++) { 
    cluster.fork(); 
    } 

    Object.keys(cluster.workers).forEach(function(id) { 
    console.log("I am running with ID : "+ cluster.workers[id].process.pid); 
    list[cluster.workers[id].process.pid] = 0; 
    }); 

    cluster.on('exit', function(worker, code, signal) { 
    console.log('worker ' + worker.process.pid + ' died'); 
    }); 
} else { // Rest of the logic with all Processes goes here. 

     // Get the Process ID of the current process in execution. 
     var pid = cluster.worker.process.pid; 
     console.log("This is process " + pid + " working now.\n"); 

     // Verify if Port is being used. 
     portInUse(PORT, function(returnValue) { 
     if(returnValue) { // Become a Client to the Server 
      console.log("port " + PORT + " is being used.\n\n"); 
      becomeClient(pid); 
     } else { // Become a Server 
      console.log("port" + PORT + " is not being used.\n\n"); 
      becomeServer(pid); 
     } 
     }); 
} 

function becomeServer(pid) { 
    var server = list[pid]; 

    server = net.createServer(function (socket) { 
    socket.write('Hello Server 1\r\n'); 
    socket.end("hello"); 
    console.log("Someone connected to Server 1. \n"); 
    socket.pipe(socket); 
    }); 

    server.listen(PORT, function(){ 
    console.log("Process " + pid + " has become the Server on Port " + PORT); 
    }); 

    server.on("error", function() { 
    console.log("there was an error on Process " + pid); 
    console.log("this error was becoming a Server."); 
    }); 
} 

function becomeClient(pid) { 
    var client = list[pid]; 

    client = net.connect({port: PORT}, function() { 
    list[pid].write("I am connected to the port and my pid is " + pid); 
    }); 

    client.on('data', function(data) { 
    console.log(data.toString()); 
    list[pid].end(); 
    }); 

    client.on('end', function() { 
    console.log('disconnected from server'); 
    }); 
} 

А вот выход:

enter image description here

Таким образом, первый процесс (в этом случае процесс 9120) становится сервером на порт 1337, но то второй процесс не обнаруживает, что порт используется и как-то становится сервером (я бы ожидал здесь EADDRINUSE, не уверен, почему он не показывает никаких ошибок).

Любая помощь или пояснение относительно того, почему это не работает, будем очень благодарны.

Спасибо,

+0

Я не эксперт по кластеру, но я считаю, что это работает по назначению. Работники кластерного узла могут прослушивать одни и те же порты, если вы этого желаете. Мастер-процесс - это тот, который фактически связывается, пока другие просто слушают. Подробнее здесь: https://nodejs.org/api/cluster.html –

ответ

1

Это ожидаемое поведение, и это как cluster модуль работает (по умолчанию). Это позволяет легко отправлять входящие запросы на один и тот же порт среди доступных рабочих.

1

Большая часть точки cluster предполагает совместное использование портов, так что вы можете иметь несколько рабочих в очереди на обслуживание запросов. Рабочие обрабатывают только запрос порта от ведущего, который фактически открывает порт, а затем мастер передает запросы всем работникам, которые запросили этот порт.

Смежные вопросы