[英]How to use a custom No Internet Connection Available layout when user is offline?
[英]How to maintain Channel API connection when internet is offline
我正在使用Google AppEngine的Channel API。 由於用戶的網絡連接,我在重新啟動丟失的連接時遇到了一些問題。 當您斷開Internet連接時,通道將調用onError,但不會調用onClose。 就JavaScript對象而言,通道套接字是打開的。
您如何處理由於互聯網問題導致的連接丟失? 我在想1)通過觸發關閉通道並在與應用程序某處的通道無關的RPC首次成功執行時(這表明Internet再次存在)來關閉通道並重新打開它;或2)使用運行所有時間並ping服務器以獲取網絡狀態(這是引入長時間輪詢的目的,以避免以此方式消耗不需要的資源)。 任何其他想法都會很棒。
觀察:當互聯網連接中斷時,將以增量間隔(10秒,20秒,40秒)兩次調用onError。 互聯網連接恢復后,頻道不會恢復連接。 它停止工作,沒有任何跡象表明它已經死了。
謝謝。
當您看到JavaScript控制台時,大概會看到“ 400 Unknown SID Error”。 如果是這樣,這是我的解決方法。 這是AngularJS的服務模塊,但請查看onerror回調。 請嘗試這種解決方法,讓我知道它是否有效。
補充:我忽略了回答您的主要問題,但是在我看來,除非實際ping通“互聯網”,否則很難確定您是否已連接到Internet。 因此,您可能需要進行一些調整,以使用類似於以下代碼的重試邏輯。 在下面的示例中,我僅重試3次,但是您可以通過一些補償來做更多。 但是,我認為處理此問題的最佳方法是,當應用消耗重試最大計數時,您可以指示用戶該應用失去了連接,理想情況下,它會顯示一個按鈕或一個鏈接以重新連接到頻道服務。
而且,您還可以在服務器端跟蹤連接,請參閱: https : //developers.google.com/appengine/docs/java/channel/#Java_Tracking_client_connections_and_disconnections
app.factory('channelService', ['$http', '$rootScope', '$timeout',
function($http, $rootScope, $timeout) {
var service = {};
var isConnectionAlive = false;
var callbacks = new Array();
var retryCount = 0;
var MAX_RETRY_COUNT = 3;
service.registerCallback = function(pattern, callback) {
callbacks.push({pattern: pattern, func: callback});
};
service.messageCallback = function(message) {
for (var i = 0; i < callbacks.length; i++) {
var callback = callbacks[i];
if (message.data.match(callback.pattern)) {
$rootScope.$apply(function() {
callback.func(message);
});
}
}
};
service.channelTokenCallback = function(channelToken) {
var channel = new goog.appengine.Channel(channelToken);
service.socket = channel.open();
isConnectionAlive = false;
service.socket.onmessage = service.messageCallback;
service.socket.onerror = function(error) {
console.log('Detected an error on the channel.');
console.log('Channel Error: ' + error.description + '.');
console.log('Http Error Code: ' + error.code);
isConnectionAlive = false;
if (error.description == 'Invalid+token.' || error.description == 'Token+timed+out.') {
console.log('It should be recovered with onclose handler.');
} else {
// In this case, we need to manually close the socket.
// See also: https://code.google.com/p/googleappengine/issues/detail?id=4940
console.log('Presumably it is "Unknown SID Error". Try closing the socket manually.');
service.socket.close();
}
};
service.socket.onclose = function() {
isConnectionAlive = false;
console.log('Reconnecting to a new channel');
openNewChannel();
};
console.log('A channel was opened successfully. Will check the ping in 20 secs.');
$timeout(checkConnection, 20000, false);
};
function openNewChannel(isRetry) {
console.log('Retrieving a clientId.');
if (isRetry) {
retryCount++;
} else {
retryCount = 0;
}
$http.get('/rest/channel')
.success(service.channelTokenCallback)
.error(function(data, status) {
console.log('Can not retrieve a clientId');
if (status != 403 && retryCount <= MAX_RETRY_COUNT) {
console.log('Retrying to obtain a client id')
openNewChannel(true);
}
})
}
function pingCallback() {
console.log('Got a ping from the server.');
isConnectionAlive = true;
}
function checkConnection() {
if (isConnectionAlive) {
console.log('Connection is alive.');
return;
}
if (service.socket == undefined) {
console.log('will open a new connection in 1 sec');
$timeout(openNewChannel, 1000, false);
return;
}
// Ping didn't arrive
// Assuming onclose handler automatically open a new channel.
console.log('Not receiving a ping, closing the connection');
service.socket.close();
}
service.registerCallback(/P/, pingCallback);
openNewChannel();
return service;
}]);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.