2015-03-23 3 views
1

Я функция NodeJS/Express (4.10.2), который вызывает внешнюю подпроцесс через икру:Выполните действия по изменению страницы или близко

app.get('/', function(req, res){ 
    res.sendFile(__dirname + '/index.html'); 
    var spawn = require('child_process').spawn; 
    var java = spawn("java", ['-cp', 'lib\\*;bin', 'com.my.app.App']); 
    ... 
} 

То, что я хотел бы сделать, это добавить какой-то анонимный функция, которая будет вызываться при изменении страницы, вкладка закрыта или даже обновлена. Короче говоря, я бы хотел убить порочный процесс!

Google не очень хорошо разбирается в этом.

+0

Почему вы хотите, чтобы процесс работал во время просмотра страницы и только во время просмотра страницы? Похож на потенциальную проблему [XY] (http://meta.stackexchange.com/a/66378) мне – Plato

+0

Также может быть способ сохранить запрос открытым, т. Е. [Длинный опрос] (https: // github.com/pascalopitz/long_polling_example/blob/master/test.js) и получить событие, когда соединение будет закрыто. ваша проблема действительно зная, когда нужно называть java.kill() и как сохранить ссылку вокруг – Plato

ответ

1

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

Затем добавьте обработчик unload на странице в Javascript, чтобы отправить запрос на новый URL с таким уникальным значением, чтобы вы могли совершить убийство.

например. Ваш экспресс-код становится чем-то вроде:

var javaSessions = { 
    _counter: -1 
}; 
app.get('/', function(req, res){ 
    res.sendFile(__dirname + '/index.html'); 
    var spawn = require('child_process').spawn; 
    var javaSessionId = javaSessions._counter++; 
    res.cookie('java_session_id', javaSessionId); 
    var java = spawn("java", ['-cp', 'lib\\*;bin', 'com.my.app.App']); 
    javaSessions[javaSessionId] = java; 
    ... 
}); 
app.get('/unload/:id', function (req, res) { 
    var java = javaSessions[req.params.id]; 
    javaSessions[req.params.id] = null; 
    java.kill(); 
}); 

Затем в index.html, добавьте следующую разметку вниз в нижней (при условии, что вам не нужно целевой браузеры старше о Internet Explorer 8):

<script type="text/javascript"> 
window.onunload = function() { 
    var req = new XMLHttpRequest(), 
     javaSessionId = document.cookie.replace(/(?:(?:^|.*;\s*)java_session_id\s*\=\s*([^;]*).*$)|^.*$/, "$1"); // regex from https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie#Example_.232.3A_Get_a_sample_cookie_named_test2 
    req.open("GET", "/unload/" + javaSessionId); 
}; 
</script> 

Вы также можете получить значение cookie из запроса, вместо того, чтобы явно прочитать его в Javascript и отправить его как параметр URL. Он может быть отправлен с запросом.

Вам нужно будет протестировать все это, это все очень гипотетический код, который вам придется попробовать самостоятельно.

+0

Nice Я попробую это - хотя я надеялся, что у NodeJS были встроенные функции, которые могли бы обнаружить, когда конечный пользователь перешел со страницы (поскольку он должен определить, когда не нужно «сервер» страницы больше в середине потока?) –

+0

Если вы просто отвечаете на запрос, как только ответ отправлен, как правило, выражение не хранит ничего вокруг. Это то, что имеется в виду, когда говорят, что HTTP является «без гражданства». Каждый запрос обрабатывается так, как если бы он был первым, который он когда-либо получал. Если вы хотите сохранить состояние на сервере, вам нужно сделать все вручную. – GregL

+0

Единственный возможный способ, которым сервер мог бы узнать, отменяет ли клиент запрос, является ли клиент прерывается, пока сервер по-прежнему отправляет данные. Но когда все, что вы делаете, отправляет некоторый HTML, с некоторыми заголовками (в том числе с файлом cookie в этом случае), как только он будет получен клиентом, сервер забудет все об этом клиенте и этом запросе. – GregL

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