実際のオンライン、オフラインイベント

オンラインイベント、オフラインイベントの出現により、多くの開発者、特にモバイルWebサービスは大きな期待を寄せています。 オンラインでもオフラインでも、ユーザーがインターネットにアクセスできることを教えてくれるように見えますが、実際はそうではありません。 彼らの行動の詳細は、かつて彼のブログで Rezigについて説明しました。







簡単に説明すると、オンライン、オフラインは、ユーザーが手動でオフラインに切り替えたこと、またはネットワークへの単一の接続がないことを知らせます。 実際、これらの2つのイベントは表示される形式では役に立たない-私は誰が手動でタブをオンライン/オフラインモードに切り替えるのかわからないし、ネットワーク接続ではすべてが悪い。 そして、もちろん、先史時代のブラウザはこれらのイベントを知りません。



洗練された100%のクロスブラウザソリューションにより、実際のオンラインイベント、オフラインイベントを取得できます。



ユーザーがインターネットに接続しているかどうか、またはWebサービスに接続しているかどうかを確認するイベントを取得する必要があります。



アルゴリズム(LIP-Long Ping Image):

1.新しい画像で画像を作成します

2. onload onerrorをハングさせます

3. pingサーバーの長いポーリングリソースへのパスを記述します

4.何らかの理由で接続が切断された場合、ブラウザはサーバーへのハング接続を確立します-インターネットが落ちた、http 50x、onerrorイベントが発生します。 ここでは、サービスがオフラインであることを100%確認するために、今度は「高速」の別の画像を作成します。 この図でonerrorが機能した場合、サービスは完全にオフラインです。 一定の間隔の後、画像のping接続を上げようとします。



解決策は、絶対にクロスブラウザーおよびクロスドメインです。 オフラインへの応答2〜4秒、オンラインへの応答0〜15秒。



気づいた問題:

1. Operaは、クリスマスツリーのように、長い画像の接続中に「読み込み中...」を修正することは不可能であり(iframe、css url、sseを試しました)、永遠の「読み込み中...」がうっとうしいことをユーザーに裏切ります。 Operaの場合、長い接続は確立されませんが、単に一定の間隔で「高速」画像が尋問されます-それほど速くなく、少し費用がかかりますが、やるべきことはありません。

2. FFユーザーは、ページをロードするときにEscキーを押すと長い接続を切断できます-preventDefaultで修正されました。

3.インターネットを物理的に切断する(コードを抜く)と、すべてのブラウザーがハング接続をリセットしないため、オフラインになりません。



利点:

1.最も古くても、すべてのブラウザのカバレッジ

2.オフライン/オンラインへの高速応答

3. pingサーバーの機能を実行するためにnginxを強化し、サーバー側でわずかなオーバーヘッドを取得できます。



短所:

1.毎分約1Kbの小さなトラフィックリーク(セッションあたり1kbにコストを削減する機能を備えています)

2. Pingサーバーを上げる必要性

3.多数のハング接続

4. pingサーバーがメインサーバーと同じドメインにある場合、可能な4つのHTTP接続のうち1つを占有します。



コード



このすべて、ソースコードを含むアーカイブ、および以下の例をスクロールできます。



ping.php-pingサーバー

<?php isset($_GET['long']) && sleep(55); header("Content-type: image/gif"); header("Expires: Wed, 11 Nov 1998 11:11:11 GMT"); header("Cache-Control: no-cache"); header("Cache-Control: must-revalidate"); // 1x1 gif printf("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c" . "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", 71,73,70,56,57,97,1,0,1,0,128,255,0,192,192,192,0,0,0,33, 249,4,1,0,0,0,0,44,0,0,0,0,1,0,1,0,0,2,2,68,1,0,59); ?>
      
      







nginx HttpEmptyGifModuleを介した別のオプションがあります

 location = /_.gif { empty_gif; }
      
      





nginxに長いリクエストを実装する方法がわからないので、PhPにオプションを追加しました。



Ping.js

 /** * @fileOveriew Long Polling Image Ping */ (function (window, Image) { /** * Long Polling Image Ping * * Way to detect user's inernet connection */ var Lpip = { BASE_URL: 'ping.php', /** * Long polling request URL. Can be crossdomain */ LONG_POLLING_IMAGE_URL: '?long', /** * Common image request. Can be crossdomain */ IMAGE_URL: '', RECONNECT_TIMEOUT: 15000, _image: null, _stage: 2, _makeImage: function (url) { var image = new Image(); image.onload = Lpip.onImageLoad; image.onerror = Lpip.onImageError; image.src = url + (url.match(/\?/) ? '&' : '?') + Math.random(); return Lpip._image = image; }, /** * @type Boolean */ online: false, /** * @type Boolean */ offline: false, /** * Long polling image request */ watch: function () { // Opera fix if (window.opera) { window.setTimeout(function () { Lpip._makeImage(Lpip.BASE_URL + Lpip.IMAGE_URL); }, Lpip.RECONNECT_TIMEOUT); return; } // For other browsers Lpip._makeImage(Lpip.BASE_URL + Lpip.LONG_POLLING_IMAGE_URL); }, /** * Quick image request */ quick: function () { Lpip._makeImage(Lpip.BASE_URL + Lpip.IMAGE_URL); }, onImageLoad: function () { if (!this.width) { // Error Lpip.onImageError.call(this); } else { // Image ok if (Lpip._stage > 1) { // Internet connection up! Lpip.onConnectionUp(); Lpip.offline = !(Lpip.online = true); } // Reset errors Lpip._stage = 0; // Continue requesting Lpip.watch(); } }, onImageError: function () { Lpip._stage += 1; if (Lpip._stage > 1) { if (Lpip._stage === 2) { // User's internet connection down... Lpip.onConnectionDown(); Lpip.offline = !(Lpip.online = false); } // Try reconnect window.setTimeout(Lpip.quick, Lpip.RECONNECT_TIMEOUT); } else { // Maybe long polling request aborts for some resons // Try to get "quick image" Lpip.quick(); } }, onConnectionUp: function () { window.console && window.console.log('onConnectionUp'); }, onConnectionDown: function () { window.console && window.console.log('onConnectionDown'); } }; // Exporting Lpip window.Ping = { /** * Inits Ping * * @param {Object} [options] * @param {Number} [options.reconnectTimeout=15000] * @param {String} [options.baseUrl='ping.php'] */ init: function (options) { Lpip.RECONNECT_TIMEOUT = options.reconnectTimeout || Lpip.RECONNECT_TIMEOUT; Lpip.BASE_URL = options.baseUrl || Lpip.BASE_URL; // User can cancel long polling request by pressing Esc button in Firefox or Opera if (window.addEventListener) { window.document.addEventListener('keypress', function (event) { if (event.keyCode === 27) { event.preventDefault(); } }, false); } Lpip.quick(); }, /** * Connection up event helper * * Supports only one listener * * @param {Function} callback */ connectionUp: function (callback) { Lpip.onConnectionUp = callback; }, /** * Connection up event helper * * Supports only one listener * * @param {Function} callback */ connectionDown: function (callback) { Lpip.onConnectionDown = callback; }, /** * @returns {Boolean} */ isOnline: function () { return Lpip.online; }, /** * @returns {Boolean} */ isOffline: function () { return Lpip.offline; } }; }(this, this.Image));
      
      







使用例

 <body> <button onclick="checkConnectionStatus()">Connection Status</button> <pre id="log"></pre> <script type="text/javascript" src="Ping.js"></script> <script type="text/javascript"> (function (window, Ping, log) { log.innerHTML += 'Lpip is watching...<br/>'; Ping.connectionUp(function () { log.innerHTML += 'Connection Up<br/>'; }); Ping.connectionDown(function () { log.innerHTML += 'Connection Down<br/>'; }); // call on window.onload to prevent "loading... status" window.onload = function () { Ping.init({ 'baseUrl': '/lpip/ping.php', 'reconnectTimeout': 15000 }); }; window.checkConnectionStatus = function () { window.alert(Ping.isOnline() ? 'Online' : 'Offline'); } }(this, this.Ping, this.document.getElementById('log'))); </script> </body>
      
      







実例: azproduction.ru/lpip (長時間チェックしないでください)

ソース: narod.ru/disk/6061703001/Ping.rar.html



批判、提案を歓迎します。 誰かがpingサーバーの変種をnginxで書いてくれたら嬉しいです。



All Articles