我正在尝试实现可在桌面,Android和iOS上运行的HTML5应用。该应用程序的主要功能是向服务器无线发送有关要运行的脚本以及从该服务器推送有关这些脚本状态的常规消息的命令。
服务器正在运行nodejs,我决定使用Server Sent Events来执行推送通知。这要求我在Android上使用Firefox,因为原生Android浏览器不支持SSE。
我的实现一切正常:节点服务器正在发布事件,我的客户端HTML5 / javascript在桌面chrome / firefox / safari,我的iPod iOS6和我的Android 2.2手机上正常发布。
但是,我需要处理4种常见情况:
Chrome / Safari在桌面和iPod上表现完美,如下所示:如果服务器崩溃,网站会在服务器再次启动时自动重新连接并获取推送的消息,如果浏览器应用程序进入后台无论什么原因,它仍然在后台获取这些消息,或者至少在它回到前台后自动重新连接。
但是,无论是在台式机上还是在Android上,Firefox都非常渴望永久关闭该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);
}
谢谢!
答案 0 :(得分:3)
我只知道一个已在许多库中使用的解决方案: “心跳”消息 - 在客户端,您可以检查,如果在10秒内没有从服务器收到“随机数”(5000秒+一些延迟) - 连接似乎被破坏,您应该重新连接 (使用原生EventSource,您可以使用“close”方法,而不是创建新的EventSource,或者您可以尝试https://github.com/Yaffle/EventSource)