Я пытаюсь реализовать приложение HTML5, которое будет работать на рабочем столе, Android и iOS. Основная функция приложения — отправлять по беспроводной сети команды на сервер о том, какие сценарии запускать, и получать регулярные сообщения, отправляемые с этого сервера, о состоянии этих сценариев.
На сервере работает nodejs, и я решил использовать события, отправленные сервером, для отправки push-уведомлений. Это требует, чтобы я использовал Firefox на Android, поскольку родной браузер Android не поддерживает SSE.
В моей реализации все работает нормально: сервер узла публикует события, как и должен, и мой HTML5/javascript на стороне клиента отлично их подхватывает на рабочем столе chrome/firefox/safari, на моем iPod iOS6 и моем телефоне Android 2.2.
Однако есть 4 распространенные ситуации, с которыми мне нужно справиться:
- устройство теряет сигнал wi-fi
- сбой сервера nodejs (надеюсь, это не часто!)
- перевести браузер в фоновый режим на iPod/Android при просмотре другого приложения и т. д.
- блокировка экрана на iPod/Android во время работы браузера
Chrome/Safari отлично ведут себя как на рабочем столе, так и на iPod следующим образом: если сервер дает сбой, сайт автоматически переподключается и получает push-сообщения, как только сервер снова включится, и если приложение браузера по какой-либо причине переходит в фоновый режим, он по-прежнему получает эти сообщения в фоновом режиме или, по крайней мере, автоматически переподключается, как только возвращается на передний план.
Однако Firefox, как на настольном компьютере, так и на Android, слишком стремится навсегда закрыть это соединение EventSource. Как только браузер теряет соединение с сервером либо из-за сбоя сервера, либо из-за перевода приложения Firefox в фоновый режим, либо из-за блокировки экрана, соединение EventSource разрывается и никогда не пытается восстановить соединение. Конечно, вы можете просто перезагрузить страницу, когда вернетесь на нее, но это раздражает, особенно в случае, когда вам нужно заблокировать экран, потому что вам нужно положить телефон в карман (это приложение нужно использовать в некоторые походные ситуации).
Может ли кто-нибудь порекомендовать какое-либо решение для этого, кроме постоянной перезагрузки страницы в Android Firefox? Ниже моя фиктивная реализация, просто отправляющая случайные числа каждые 5 секунд.
Сервер в /main/src
src : function(req, res) {
req.socket.setTimeout(Infinity);
// send headers for event-stream connection
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
res.write('\n');
var messageCount = 0;
var process;
function printEvent() {
messageCount++;
rand = Math.floor((Math.random()*10000)+1);
res.write('id: ' + messageCount + '\n');
res.write("data: " + rand + '\n\n');
process = setTimeout(printEvent, 5000);
}
printEvent();
res.socket.on('close', function () {
res.end();
clearTimeout(process);
});
}
Клиент
var source = new EventSource('/main/src');
source.onopen = function(e){
$("#test").html("Connected to server. Waiting for data...");
}
source.onmessage = function(e){
$("#test").html("MSG: " + e.data);
}
source.onerror = function(e){
var txt;
switch(e.target.readyState){
case EventSource.CONNECTING:
txt = 'Reconnecting...';
break;
case EventSource.CLOSED:
txt = 'Connection failed. Will not retry.';
break;
}
$("#test").html("Error: " + txt);
}
Спасибо!!