1

Я как-то новичок в nodejs и дочерних процессах и в некоторых случаях сталкиваюсь с некоторыми проблемами. Что-то в фоновом режиме: У меня есть nodejs-Websocket-Server, который загружает HTML-страницу любому пользователю, который подключается. Если пользователь нажимает кнопку на HTML, он отправляет сообщение серверу, чтобы он начал процесс захвата изображения (в качестве дочернего процесса в узле). Таким образом, вы можете сравнить это с каким-то бесконечным циклом, который выполняется в дочернем. Пока все хорошо, это работает для меня.Запуск и остановка дочерних процессов из основного процесса только при необходимости в nodejs

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

Это фрагмент из основного процесса («старт» является истинным или ложным, в зависимости от того, если пользователь нажал кнопку пуска Каждый раз, когда пользователь нажимает на кнопку «старт» изменяет свое состояние.):

var aCapLive = child.fork(__dirname + "/cp_capture_liveimg_async.js"); //Livebild 
if (start) aCapLive.send(start); 
else aCapLive.send(start); 

и это от ребенка:

var i = 0; 
process.on("message", function(message) 
{ 
    while(message) 
    { 
     console.log("CP aCapLive received message: Iteration " + i++); 
    } 
    console.log("CP aCapLive is going to exit now..."); 
    process.exit(); 
} 

Очевидно, что это не работает для меня, потому что я бегу в моем цикле и не могу обнаружить никаких изменений в «сообщении». Я был бы очень благодарен, если бы у кого-нибудь были какие-то идеи :)

ответ

0

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

Я думаю, что вы чего-то хотеть больше, как это:

var i = 0; 
process.on("message", function(message) 
{ 
    if(message) 
    { 
     console.log("CP aCapLive received message: Iteration " + i++); 
    } 
    else 
    { 
     console.log("CP aCapLive is going to exit now..."); 
     process.exit(); 
    } 
}); 

Если вы хотите бесконечный цикл, вы должны вернуть управление в цикл обработки событий после каждой итерации. Это позволит шанс на новые сообщения, чтобы прийти в. Пример:

var _message; 
var _running = false; 
process.on("message", function (message) 
{ 
    _message = message; // update the _message var when a new one comes in 
    if (!_running) // this just prevents multiple loops from being started. 
    { 
     _running = true; 
     run(); 
    } 
}); 

var i = 0; 
function run() 
{ 
    if(_message) 
    { 
     console.log("CP aCapLive received message: Iteration " + i++); 
     setImmediate(run); // <-- this causes an infinite non-blocking loop 
    } 
    else 
    { 
     console.log("CP aCapLive is going to exit now..."); 
     process.exit(); 
    } 
} 

Если message будет то же самое каждый раз, что вы на самом деле хотите это система переключения, как, например:

var _message = false; 
process.on("message", function() 
{ 
    _message = !_message; // update the _message var when a new one comes in 
    if (_message) 
     run(); 
}); 

var i = 0; 
function run() 
{ 
    if(_message) 
    { 
     i++; 
     if (i % 10000 === 0) 
      console.log("CP aCapLive received message: Iteration " + i); 
     setImmediate(run); // <-- this causes an infinite non-blocking loop 
    } 
    else 
    { 
     console.log("CP aCapLive is going to exit now..."); 
     process.exit(); 
    } 
} 

Вот код, родительский процесс, который я использовал, чтобы проверить это:

var childProcess = require('child_process'); 

var proc = childProcess.fork('child.js'); 
proc.send(true); 
setTimeout(function() { proc.send(true); }, 4000); // send second message 

Выход:

CP aCapLive received message: Iteration 10000 
CP aCapLive received message: Iteration 20000 
CP aCapLive received message: Iteration 30000 

... full output omitted for brevity ... 

CP aCapLive received message: Iteration 1660000 
CP aCapLive received message: Iteration 1670000 
CP aCapLive received message: Iteration 1680000 
CP aCapLive is going to exit now... 
+0

Ну, да, у меня было это как раньше, но проблема в том, что я ХОЧУ выполнить бесконечный цикл, когда «сообщение» истинно. Когда пользователь снова нажимает кнопку, сообщение должно измениться на false, и цикл должен остановиться. Может быть, у меня есть неправильная идея сделать что-л. как это, но thats atm единственный способ, которым я могу это представить;) – Fidel90

+0

Хорошо, есть способ сделать это, но это сложнее ... здесь, я напишу это. –

+0

@ Fidel90 Был ли мой адрес для редактирования, что вы спрашивали? –

0

Я сделал некоторое исправление ошибок, так что теперь можно запускать и останавливать цикл так часто, как я хочу (замена process.exit() с clearImmediate (ID), так что этот процесс может быть выполнен снова и снова):

var _message; 
var _running = false; 
var i = 0; 

process.on("message", function (start) 
{ 
    _message = start; // update the _message var when a new one comes in 
    if (!_running) // this just prevents multiple loops from being started. 
    { 
     _running = true; 
     run(); 
    } 
}); 


function run() 
{ 
    if(_message) 
    { 
     console.log("CP aCapLive received message: Iteration " + i++); 
     var id = setImmediate(run); // <-- this causes an infinite non-blocking loop 
    } 
    else 
    { 
     console.log("CP aCapLive is going to exit now..."); 
     _running = false; 
     clearImmediate(id); 
    } 
}