Chrome on Android :连接在 30 分钟后断开
Chrome on Android : connection become dead after 30 minutes
我们正在使用我们自己的通知系统构建一个聊天室,不依赖于 GCM,而是使用 service worker + SSE。
在桌面上没问题,但在移动 android 应用程序(使用 cordova-crosswalk,chromium 53)上。
长 运行 通知连接在 20-30 分钟后卡住,它在前台 activity。
它不会因错误而死,只是不会接收数据。完全没有错误,这很奇怪。无法重新连接,因为我们根本不知道连接是否已断开。
最干净的方法是什么?每 5 分钟重新启动一次连接是一种想法,但它并不干净。
代码
runEvtSource(url, fn) {
if (this.get('session.content.isAuthenticated') === true) {
var evtSource = new EventSource(url, {
withCredentials: true
});
}}
主动重新连接代码
var evtSource = this.runEvtSource(url, fn)
var evtSourceErrorHandler = (event) => {
var txt;
switch (event.target.readyState) {
case EventSource.CONNECTING:
txt = 'Reconnecting...';
evtSource.onerror = evtSourceErrorHandler;
break;
case EventSource.CLOSED:
txt = 'Reinitializing...';
evtSource = this.runEvtSource(url, fn)
evtSource.onerror = evtSourceErrorHandler;
break;
}
console.log(txt);
evtSource.onerror = evtSourceErrorHandler
我通常在 SSE 连接之上添加一个保持活动层。这种情况并不经常发生,但套接字可能会在没有正确终止的情况下终止,因此您的连接会安静下来并且您不会收到错误。
所以,一种方法是,在您的获取数据函数中:
if(timer)clearTimeout(timer);
timer = setTimeout(reconnect, 30 * 1000);
...process the data
换句话说,如果自上次获取数据以来已超过 30 秒,请重新连接。根据您发送的数据的频率选择一个值:如果 10% 的时间在数据事件之间存在 60 秒的间隔,但绝不会出现 120 秒的间隔,那么将超时设置为高于 120 秒是有意义的.
您可能还想通过将常规消息从服务器推送到客户端来保持活动状态。如果来自服务器的消息频率非常不规则,这是一个好主意。例如。我可能让服务器每 30 秒发送一次当前时间戳,并在客户端上使用 45 秒的保持活动超时。
顺便说一句,如果这是一个移动应用程序,请记住用户是否会欣赏减少接收聊天消息的延迟带来的好处,而不是电池寿命缩短的缺点。
我们正在使用我们自己的通知系统构建一个聊天室,不依赖于 GCM,而是使用 service worker + SSE。 在桌面上没问题,但在移动 android 应用程序(使用 cordova-crosswalk,chromium 53)上。 长 运行 通知连接在 20-30 分钟后卡住,它在前台 activity。 它不会因错误而死,只是不会接收数据。完全没有错误,这很奇怪。无法重新连接,因为我们根本不知道连接是否已断开。
最干净的方法是什么?每 5 分钟重新启动一次连接是一种想法,但它并不干净。 代码
runEvtSource(url, fn) {
if (this.get('session.content.isAuthenticated') === true) {
var evtSource = new EventSource(url, {
withCredentials: true
});
}}
主动重新连接代码
var evtSource = this.runEvtSource(url, fn)
var evtSourceErrorHandler = (event) => {
var txt;
switch (event.target.readyState) {
case EventSource.CONNECTING:
txt = 'Reconnecting...';
evtSource.onerror = evtSourceErrorHandler;
break;
case EventSource.CLOSED:
txt = 'Reinitializing...';
evtSource = this.runEvtSource(url, fn)
evtSource.onerror = evtSourceErrorHandler;
break;
}
console.log(txt);
evtSource.onerror = evtSourceErrorHandler
我通常在 SSE 连接之上添加一个保持活动层。这种情况并不经常发生,但套接字可能会在没有正确终止的情况下终止,因此您的连接会安静下来并且您不会收到错误。
所以,一种方法是,在您的获取数据函数中:
if(timer)clearTimeout(timer);
timer = setTimeout(reconnect, 30 * 1000);
...process the data
换句话说,如果自上次获取数据以来已超过 30 秒,请重新连接。根据您发送的数据的频率选择一个值:如果 10% 的时间在数据事件之间存在 60 秒的间隔,但绝不会出现 120 秒的间隔,那么将超时设置为高于 120 秒是有意义的.
您可能还想通过将常规消息从服务器推送到客户端来保持活动状态。如果来自服务器的消息频率非常不规则,这是一个好主意。例如。我可能让服务器每 30 秒发送一次当前时间戳,并在客户端上使用 45 秒的保持活动超时。
顺便说一句,如果这是一个移动应用程序,请记住用户是否会欣赏减少接收聊天消息的延迟带来的好处,而不是电池寿命缩短的缺点。