2017-09-06 13 views
0

私は、モバイルデバイスが本当にオンライン、インターネットに接続されであることを検出するための解決策を探しています。 イオン性チェックインターネット接続

は、私は明らかに、HTTPのインターセプターで、次の方法を試してみました:

if (navigator.connection.type != Connection.NONE) alert("you're online!") 

それに伴う問題には、インターネットがメッセージを取得していないだろう持っているWiFiネットワークに接続しているユーザーは、「あなたがオンラインしているということです彼らはインターネットを持っていません。どうして?その場合、navigator.connection.type = Connection.WIFIがあります。

溶液を用いて任意のヘルプ?

私は明らかにすることができピンググーグル、それはGoogleが、私は自分のサーバーに過負荷をかけるのです感謝します必ずそうエレガントではないではありません。

また、私はすべての私の失敗したhttpリクエストの応答を引くと思ったが、ユーザーはインターネットを持っているか、要求が別の理由で失敗した場合ならば、私は結論付けることができていることに基づくかどうかわからないしました。

+0

Firebaseを使用していた場合、ユーザーの接続(私が使用していてうまく動作しているようです)を確認するのに非常に便利な方法があります。それとは別にAngularとの接続をチェックすることに関する[this](https://stackoverflow.com/a/16242703/7468384)の質問と回答があります。 –

+1

よく_ _ _ _ _ _接続しているかどうかを知らせるシステムイベントはありません。設定を試す以外には、3000msのタイムアウトが必要です。あなたのサーバ上のいくつかのダミーリソースへのe GETコールを使うことができます。あるいは、あなたがping googleと言ったように - 彼らはあなたのトラフィックを処理できると思います:) – David

答えて

0

あなたは、ウェブサイトなどのサーバーに対してpingを実行し、その後、 インターネットがそうでなければ接続された任意の応答を取得するかどうかを確認することができません

0

あなたがちょうど200で応答し、サーバー側で作成したエンドポイントに呼び出して取得することができますデータなしのステータス。 navigator.connection.typeの変更が検出された場合にのみこれを行います。残りのため 、私はあなたが予期しない接続損失または200以外を扱うことができるようにあなたが作る各要求にエラーコールバック関数を実装することをお勧めして201う

0

ユーザーがOnlineかであるかどうかのEventListenerを追加することができますOffline

$ionicPlatform.ready(function(){ 
document.addEventListener("offline", offlineCallBackFunction, false); 
document.addEventListener("online", onlineCallBackFunction, false); 

}) 

あなたのコールバック関数を次のように:あなたのrun機能には次のよう

あなたは、プラットフォームに準備ができて追加する必要が

function offlineCallBackFunction() { 
      $ionicPopup.alert({ 
       title: "Internet Disconnected", 
       content: "Internet is disconnected on your device." 
      }); 

     } 

    function onlineCallBackFunction() { 
     $ionicPopup.alert({ 
      title: "Internet Connected", 
      content: "Internet is connected on your device." 
     }) 
     .then(function (result) { 
      window.location.reload(); 
     }); 
    } 

更新

上記の方法はあなたが検出し、あなたがインターネットにアクセスしているかどうかを確認するために、あなた自身のServer (API) Url。

は、それはあなたがコントロールしていないものです場合は特に、実際の要求の一部ではないホストでテストしないでください。つまり、ユーザーがwww.example.comに到達できるかどうかをテストする場合は、www.google.comにpingを実行しないでください。あなたの試行は、特にあなたのアプリが人気を得た場合、悪意のある攻撃とみなされる可能性があります。

+0

残念ながら、これはnavigator.connection.type!= Connection.NONEと同じ方法で動作します。インターネットなしでWi-Fiネットワークに接続すると、「インターネット接続済み」というメッセージが表示されます。 – Robycool

+0

@Robycool、この部分はあなたがネットワークに接続していることを伝え、あなたのAPIにアクセスしようとすると 'URL'に失敗し、' Googleにpingするのではなく、インターネットにアクセスできない場合 – Webruster

0

@デビッドが述べたように、あなたが本当に働いてインターネットに接続している場合は、あなたを教えてくれます何のシステムイベントはありません。

論理

vm.isInternetUp

ブールを作成し、ユーザが接続されていると仮定する。ユーザーが切断することができます3つの理由があります。

  1. オフラインイベントは、デバイスが無線LANのチャネルに接続されている場合は何の無線LAN、3Gやイーサネット接続
  2. がないことを意味し、ブラウザによって発射された場合は、 Wi-Fiチャンネルにインターネットはありません。
  3. インターネットなしの3G /イーサネット接続もありますが、私たちの場合は関係ありませんでした(この記事には含まれていません)。

ここで、これらの条件のいずれかが発生したときに検出する必要があります。vm.isInternetUpはfalseになります。そのフラグをオフラインにすると、肯定的な応答が得られるまで、APIへのHTTP要求でループを開始します。

これは非常に面倒ですが、このようにして、インターネット接続のステータスを確認するためにhttpリクエストを継続的に送信することはありません。ユーザーがオンラインに戻ると、1つのhttpだけがサーバーに到達します。

これを実装するさまざまな方法があります

コード(オンライン/オフラインイベントと@ webrusterの回答を見てください)。インターセプタを使用するのは、自分の特定のニーズに最も適しているからです。理由の1のために

vm.isInternetUp = true //assume internet is up at startup 
    var interceptor = { 
    request: function(config) { 
     return vm.checkForInternet(config); 
    }, 
    responseError: function(reject){ 
     return vm.handleBadWifi(reject) 
    } 
    } 

は、私たちはWi-Fiに接続しているかどうか、すべての要求でチェックするの角度のhttp request interceptorを使用しています。そうでなければ、私たちはオフラインであることを意味します。

vm.checkForInternet = function(config) { 

    if (angular.isUndefined(window.Connection)) { 
     // The project is run in a web browser so window.Connection doesn’t exist. Assume we have internet. 
     console.log("window.Connection doesn't exist") 
     return config; 
    } 
    //if there is no internet 
    if (navigator.connection.type === Connection.NONE || !vm.isInternetUp) { 
     vm.isInternetUp = false 
     vm.reconnect(); 
     } 
     else { 
     console.log("connected but bad wifi") 
     } 
    } 
    return config; 
    } 

理由2のために、私はすべてのhttp要求を傍受して$ http responseError interceptorを使用します。ドキュメントに記載されているように、reject.status = -1 usually means the request was aborted;私たちはインターネット接続がないと結論づけます。

最後に、肯定的な要求を受け取った直後に再接続ループが停止します。 $ httpインターセプタの中にあるので、Angleの$ httpサービスを使うことができないので、かなり長いです。 $ httpを使用すると、循環依存関係が発生します。

vm.reconnect = function() { 
    //Restart only if we were previously disconnected and after checking that we really have the internet 
    if (!vm.isInternetUp & !vm.reconnecting) { 
     console.log("attempting http call") 
     vm.reconnecting = true; 
     //backend-host is only pinged if internet was previously disconnected. In this way it does not overload the server. 
     //we don't use $http because that would induce a circular dependency (we're in an $http interceptor here). As this is a pure js http call this request will not be intercepted. 
     pureJsHttpGet(backendHost + 'projects/',vm.reconnectSuccess,vm.reconnectError) 
    }   
    } 
    vm.reconnectSuccess = function() { 
    vm.isInternetUp = true; 
    vm.reconnecting = false; 
    } 
    vm.reconnectError = function (error) { 
    $timeout(function() { 
     vm.reconnecting = false; 
     vm.checkForInternet(); 
    },3000) 
    console.error("Did not manage to find an internet connection. Retrying in 3 sec", error) 
    if (navigator.connection.type === Connection.WIFI){ 
     //create a fake reject error so that the wifi errorhandler knows the request failed 
     var reject = {status:-1} 
     vm.handleBadWifi(reject)  
    } 
    } 
    function pureJsHttpGet(theUrl, successCallback, errorCallback){ 
     var xmlHttp = new XMLHttpRequest(); 
     xmlHttp.onreadystatechange = function() { 
      if (xmlHttp.readyState == 4 && xmlHttp.status == 200) 
      successCallback(xmlHttp.responseText); 
      else if (xmlHttp.readyState == 4 && xmlHttp.status == 0) 
      errorCallback(xmlHttp) 
     } 
     xmlHttp.open("GET", theUrl, true); // true for asynchronous 
     xmlHttp.send(null); 
    } 
関連する問題