ネットワーク接続イベントと可用性の変更を管理する方法 (HTML)
[ この記事は、Windows ランタイム アプリを作成する Windows 8.x および Windows Phone 8.x 開発者を対象としています。Windows 10 向けの開発を行っている場合は、「最新のドキュメント」をご覧ください]
このトピックでは、Windows.Networking.Connectivity 名前空間のクラスを使って、ネットワーク接続状態の変更通知の受信を登録する方法と、現在の状態に関する情報を取得する方法を示します。
さらに、さまざまなネットワーク シナリオで一貫したユーザー エクスペリエンスをサポートするアプリの動作について、推奨事項を紹介します。
必要条件
次の例は、JavaScript で記述されており、ネットワーク情報のサンプルに基づいています。 JavaScript を使った Windows ランタイム アプリの作成についての一般的なヘルプは、「JavaScript を使った初めての Windows ランタイム アプリの作成」をご覧ください。
ConnectionProfile とは何か、またそれが表す情報へのアクセス方法を知っておくことは重要です。詳しくは、「ネットワーク接続情報を取得する方法」をご覧ください。 その他のコード例については、Network Information サンプルをダウンロードしてください。
接続状態の変更イベントと見なされるのは何か
状態の変更イベントとは、個々の接続によって提供される接続の可用性、種類、またはコストの変更を意味します。最近の接続アプリでは、モバイル デバイスを使う場合に典型的なネットワーク トラバーサルが発生することがよくあります。 Windows ランタイムで新しいネットワークが検出されると、新しい接続先として自動的に追加されます。たとえば、3G/4G ネットワーク上でデバイスを使ってデータをストリーミングしているユーザーが Wi-Fi ネットワークの範囲に入ると、その新しい接続先がアプリケーションから利用できるようになります。もちろん、このことは、現在使っている可能性があるネットワークの範囲からユーザーが出たことも意味しています。
これらの可能性をすべて考慮すると、ネットワークの可用性に変化が生じたときに、より賢明な選択ができるようなロジックをアプリに備えることが重要です。既にあるネットワーク接続が、他の接続に自動でシームレスに切り替わることはありません。アプリで networkstatuschanged イベントに登録し、それに従って対応させる必要があります。
接続状態の変更イベントの通知に登録する
アプリがネットワーク状態の変更に対応するためには、それがいつ発生するのかを知る必要があります。 次のコード例は、特定の接続プロファイルに関する networkstatuschanged イベント通知に登録する方法を示しています。
非同期ネットワーク メソッドの多くは、呼び出す場合、例外を処理するようにコードを記述する必要があります。また、イベント通知に登録し、ConnectionProfile の取得を試行する Windows.Networking.Connectivity 名前空間のメソッドも、例外をスローできます。エラーについてよく理解し、適切な判断ができるように、例外ハンドラーは例外の原因についての詳しい情報を取得できます。詳しくは、「ネットワーク アプリで例外を処理する方法」をご覧ください。
// Define some variables used
// A variable to store network status change information
var internetProfileInfo = "";
// A boolean to keep track of registration for network status change notifications
var registeredNetworkStatusNotif = false;
var networkInfo = Windows.Networking.Connectivity.NetworkInformation;
//Register for Network Status Change notifications, and display new Internet Connection Profile information on network status change
function registerForNetworkStatusChangeNotif() {
// register for network status change notifications
if (!registeredNetworkStatusNotif) {
try {
networkInfo.addEventListener("networkstatuschanged", onNetworkStatusChange);
registeredNetworkStatusNotif = true;
if (internetProfileInfo === "") {
mySample.displayStatus("No network status change. ", "sample", "status");
}
catch (e) {
mySample.displayError("An unexpected exception occured: " + e.name + ": " + e.message);
}
}
}
ネットワーク シナリオが変更されたときに、アプリでネットワークの状態変更通知に既に登録している場合は、登録を解除し、新しいネットワーク シナリオの通知に再登録することが必要になる可能性があります。
//Unregister for Network Status Change notifications
function unRegisterForNetworkStatusChangeNotif() {
try {
networkInfo.removeEventListener("networkstatuschanged", onNetworkStatusChange);
internetProfileInfo = "";
}
catch (e) {
mySample.displayError("An unexpected exception occured: " + e.name + ": " + e.message, "sample", "error");
}
}
接続状態の変更の情報を取得する
次のイベント ハンドラーの例では、接続状態の変更が発生したときに、現在のインターネット接続プロファイルに関連付けられている ConnectionProfile を取得します。この ConnectionProfile を使って接続状態に関する情報を取得し、表示できます。この情報には、接続の現在の範囲、種類、コストがあり、それぞれ NetworkConnectivityLevel、NetworkTypes、NetworkCostType によって定義されます。
// Event handler for Network Status Change event
function onNetworkStatusChange(sender) {
//network status changed
internetProfileInfo = "Network Status Changed: \n\r";
try {
// get the ConnectionProfile that is currently used to connect to the Internet
var internetProfile = networkInfo.getInternetConnectionProfile();
if (internetProfile === null) {
mySample.displayStatus("Not connected to Internet\n\r");
}
else {
internetProfileInfo += getConnectionProfileInfo(internetProfile) + "\n\r";
mySample.displayStatus(internetProfileInfo);
}
internetProfileInfo = "";
}
catch (e) {
mySample.displayError("An unexpected exception occured: " + e.name + ": " + e.message, "sample", "error");
}
}
ネットワークにはさまざまな状態があり、その変化によってネットワーク状態変更イベントが発生します。これには、デバイスの ConnectionProfile、接続コスト、接続レベルが新しくなったかどうかや、その他の変更が含まれます。 前に示したイベント ハンドラーは、NetworkStateChangeEventDetails クラスを使って変更の内容を判定します。
接続状態の変更を処理するときに推奨されるアプリの動作
次の表は、接続状態の変更の主なシナリオの概要と、アプリの動作の推奨事項を示したものです。
シナリオ | 推奨される動作 |
---|---|
エラーによって接続が失われた | ネットワーク操作を再試行するだけで接続を再構築できます。これに失敗した場合は、現在の接続状態に関する情報を取得する networkstatuschanged イベントを待ちます。アプリのバックオフ間隔の値は、50 ミリ秒で始めて、再試行ごとに指数関数的に増やすことをお勧めします。 |
ネットワークが失われた | ユーザーに接続が失われた旨の通知を送り、networkstatuschanged イベントを登録し、待機します。 |
新しいネットワークが利用可能になった | モバイル デバイスの普及によって、1 つのデバイスが複数のパブリック ネットワークやプライベート ネットワークを利用する状況がよくみられるようになっています。 たとえば、ユーザーが帰宅して制限のないホーム ネットワークに接続するまでに、モバイル ブロードバンドに接続してメッセージング アプリで友達とチャットをすることがあります。Windows 8、Windows Server 2012、Windows Phone 8.1 以降の既定のポリシーでは、従量制課金接続よりも制限のないネットワークが、また、低速なネットワークよりも高速なネットワークが選ばれるようになっています。ただし、アプリによって確立された既にある接続から新しいネットワークに自動的に切り替わることはありません。新しいネットワークに切り替えるかどうかを適切に判断できるのはアプリだけなので、アプリが関与する必要があります。 ビデオ ストリームのダウンロードの完了が近い場合は、新しいネットワークに切り替えてからダウンロードを再開する意味がありません。ただし、現在のネットワークでパケットが破棄される場合、ネットワークがきわめて遅い場合、ストリーム完了までにまだ時間が必要な場合には、新しいネットワークへの切り替えが適していると考えられます。 アプリのシナリオを考えてネットワークの切り替えが妥当であると判断した場合には、新しいネットワークの検出に際して次のガイドラインに従ってください。 1. ネットワーク コストを確かめ、より適切な接続を利用できる場合はネットワーク操作を再試行する。Windows では従量制課金接続よりも制限のないネットワークが、また、低速なネットワークよりも高速なネットワークが自動的に選ばれます。 2. 再試行でネットワーク操作に成功したら、元のネットワーク操作を取り消す (ただし、そのネットワークが存在する場合に限る)。 |
ネットワーク コストが変化した | モバイル ネットワークでは特に、利用に関してきわめて特殊な制限があることが多くなっています。モバイル ブロードバンド データの上限、変動費、またはローミングの使用量が 80% を超えたためにネットワーク コストが変化した場合には、「従量制課金接続のコスト制約を管理する方法」で説明したアプリの動作が適用されます。 |
注 ネットワーク操作の再試行時のアプリの動作を最適化することもできます。たとえば、既にある接続を高速なネットワークに置き換えることができます。この場合は、StreamSocketInformation.bandwidthStatistics のようなソケット API を使って、別の接続への切り替えが適切かどうかを判断できます。
要約
このトピックでは、接続状態の変更通知に登録する方法と、それらの通知を使って、イベントが発生した ConnectionProfile から現在の状態に関する情報を取得する方法を確認しました。また、最もよくみられる状態変化のシナリオに対応するときのアプリの推奨動作も確認しました。
このトピックでは従量制課金接続への接続をはじめとするシナリオでネットワークの可用性を取り上げたほか、networkstatuschanged イベントがコストとデータ プランのプロパティに対する変更も表す場合があることを説明しました。これらのシナリオでのアプリ動作の最適な変更方法に関する情報とガイダンスについては、「従量制課金接続のコスト制約を管理する方法」をご覧ください。
関連トピック
その他
JavaScript を使った初めての Windows ランタイム アプリの作成
リファレンス
networkStatusChangedEventHandler
Windows.Networking.Connectivity
サンプル