我正在尝试实现一个可以在桌面、Android 和 iOS 上运行的 HTML5 应用程序。该应用程序的主要功能是向服务器无线发送有关要运行哪些脚本的命令,并接收从该服务器推送的有关这些脚本状态的常规消息。
服务器正在运行 nodejs,我决定使用服务器发送事件来进行推送通知。这要求我在 Android 上使用 Firefox,因为原生 Android 浏览器不支持 SSE。
我的实现一切正常:节点服务器按应有的方式发布事件,我的客户端 HTML5/javascript 在桌面 chrome/firefox/safari、我的 iPod iOS6 和我的 Android 2.2 手机上正常运行。
但是,我需要处理 4 种常见情况:
- 设备失去其 wi-fi 信号
- nodejs 服务器崩溃(希望这不常见!)
- 在浏览另一个应用程序等时将浏览器置于 iPod/Android 的后台。
- 浏览器运行时在 iPod/Android 上锁定屏幕
Chrome/Safari 在台式机和 iPod 上都表现完美,如下所示:如果服务器崩溃,网站会自动重新连接并在服务器再次启动时立即获取推送的消息,如果浏览器应用程序因任何原因进入后台,它仍然在后台收到这些消息,或者至少在它回到前台时自动重新连接。
然而,无论是桌面版还是安卓版的 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);
}
谢谢!!