StreamWebSocket を使って接続する方法 (HTML)

[この記事は、Windows ランタイム アプリを作成する Windows 8.x および Windows Phone 8.x 開発者を対象としています。Windows 10 向けの開発を行っている場合は、 「最新のドキュメント」をご覧ください]

このトピックでは、Windows ランタイム アプリで StreamWebSocket を使ってデータのストリームを送受信する方法を説明します。

StreamWebSocket クラスは、メッセージ ベースの WebSocket プロトコルのストリーム ベースのアブストラクションを生成します。これは、大きいファイル (写真やムービーなど) をクライアントとサーバー間で転送する必要がある場合に便利です。サーバーで WebSocket プロトコルがサポートされている必要があります。StreamWebSocket を使うと、メッセージ全体を 1 回の操作で読み取らなくても (MessageWebSocket のように)、読み取り操作ごとにメッセージのセクションを読み取ることができます。

StreamWebSocket クラスでは、バイナリ メッセージのみサポートされます。UTF-8 メッセージの場合、MessageWebSocket を使う必要があります。

必要条件

次の例は、JavaScript で記述されており、WebSocket のサンプルに基づいています。 JavaScript を使った Windows ランタイム アプリの作成についての一般的なヘルプは、「JavaScript を使った初めての Windows ランタイム アプリの作成」をご覧ください。このトピックでは、JavaScript の promise を使って非同期操作も実行します。このプログラミング パターンについて詳しくは、promise を使った JavaScript での非同期プログラミングに関するページをご覧ください。

Windows ランタイム アプリをネットワークに対応させるには、プロジェクトの Package.appxmanifest ファイルで必要なネットワーク機能を設定する必要があります。 アプリがクライアントとしてインターネット上のリモート サービスに接続する必要がある場合は、インターネット (クライアント) 機能が必要です。アプリがクライアントとしてホーム ネットワークまたは社内ネットワーク上のリモート サービスに接続する必要がある場合は、ホーム/社内ネットワーク機能が必要です。

  Windows Phone では、アプリに対してすべてのネットワーク アクセスを有効にするネットワーク機能は [インターネット (クライアントとサーバー)] だけです。

 

詳しくは、「ネットワーク機能を設定する方法」をご覧ください。

手順

1. StreamWebSocket オブジェクトを作ってデータを送受信する

このセクションのコードでは、新しい StreamWebSocket を作り、WebSocket サーバーに接続して、サーバーにデータを送り、応答をリッスンします。

まず、使うサーバー URI が有効であることを検証します。次に、その URI を使って WebSocket サーバーに接続し、サーバーからの応答を受け取るまで待機します。

入力 URI アドレスでは、まずユーザーが有効な URI アドレスを渡したかどうかが確認されます。アプリが既に WebSocket サーバーの URI を認識している場合、この手順は必要ありません。

Uniform Resource Identifier (URI) として無効な文字列が、Windows.Foundation.Uri オブジェクトのコンストラクターに渡されると、例外がスローされます。

JavaScript では、URI として渡される文字列を試行して解析するメソッドはありません。この場合、こうした例外をキャッチするために、URI を構築するコードを try/catch ブロックで囲みます。

このサンプルではまた、URI 内の HTTP スキーマが WS または WSS であることを確認しています。これらは、StreamWebSocket によってサポートされる唯一のスキーマであるためです。

ユーザー入力からの有効な URI がある場合、アプリは WebSocket サーバーに接続し、データを送受信できます。

ネットワークのエラーによる例外 (たとえば、接続の切断、接続エラー、HTTP サーバー エラーなど) は、いつでも発生する場合があります。これらのエラーが起きると、例外がスローされます。例外がアプリによって処理されない場合、ランタイムによってアプリ全体が終了されることがあります。 非同期ネットワーク メソッドの多くは、呼び出す場合、例外を処理するようにコードを記述する必要があります。例外の発生時に、場合によっては、問題を解決するためにネットワーク メソッドが再試行されることがあります。また、ネットワーク接続なしで、以前にキャッシュされたデータを使ってアプリを継続するように計画しなければならない場合もあります。ネットワーク例外の処理について詳しくは、「ネットワーク アプリでの例外の処理」をご覧ください。

  特定のイベントが発生したことを、ユーザーにメッセージで表示する、またはログに書き込むことができます (接続が確立されたときやエラーが発生したときなど)。サンプルでは、アプリ用に実装する必要がある displayStatus 関数が呼び出されます。

 

  書き込みと読み取りの操作を実行する writeOutgoing() 関数と readIncoming() 関数は、この後の手順で定義します。

 

  • js フォルダーを開きます。使う .js ファイルを開いて次のコードを追加します。

    
    // Define some variables we will use
    var streamWebSocket;
    var dataWriter;
    var dataReader;
    // The data to send
    var data = "Hello World";
    var countOfDataSent;
    var countOfDataReceived;
    
    function start() {
       if (streamWebSocket) {
          // The WebSocket is already running. Go ahead and immediately return,  
          // or display a message that indicates that it is running.
          return;
       }
    
       var webSocket = new Windows.Networking.Sockets.StreamWebSocket();
       webSocket.onclosed = onClosed;
    
       // WebSocket server to test connections
       // If the scheme is wss:, then the server will
       // echo back what it receives
       var uriString = "wss://echo.websocket.org";
    
       // We might get the uriString from the user so
       // we need to check that we have a valid URI
       var serverUri;
       try {
          serverUri = new Windows.Foundation.Uri(uriString);
          }
       catch (Exception) {
          displayStatus("Invalid URI, please re-enter a valid URI.");
          return;
       }
    
       if (serverUri.schemeName != "ws" && serverUri.schemeName != "wss") {
          displayStatus("Only 'ws' and 'wss' schemes supported. Please re-enter URI");
          return;
       }
    
       // Asynchronous networking methods can throw execptions
       webSocket.connectAsync(uri).done(function () {
          diaplayStatus("Connected");
    
          streamWebSocket = webSocket;
          dataWriter = new Windows.Storage.Streams.DataWriter(webSocket.outputStream);
          dataReader = new Windows.Storage.Streams.DataReader(webSocket.inputStream);
          // When buffering, return as soon as any data is available.
          dataReader.inputStreamOptions = Windows.Storage.Streams.InputStreamOptions.partial;
          countOfDataSent = 0;
          countOfDataReceived = 0;
    
          // Continuously send data to the server
          writeOutgoing();
    
          // Continuously listen for a response
          readIncoming();
    
       }, function (error) {
          var errorStatus = Windows.Networking.Sockets.WebSocketError.getStatus(error.number);
          if (errorStatus === Windows.Web.WebErrorStatus.cannotConnect ||
             errorStatus === Windows.Web.WebErrorStatus.notFound ||
             errorStatus === Windows.Web.WebErrorStatus.requestTimeout) {
             displayStatus("Cannot connect to the server");
          } else {
             displayStatus("Failed to connect: " + getError(error));
          }
       });
    }
    

2. 発信データの送信

このセクションのコードでは、WebSocket オブジェクトでサーバーにデータを送ります。

  writeError() 関数については、この後の手順で定義します。

 

  • 次のコードを .js ファイルに追加して、writeOutgoing() 関数を定義します。

    function writeOutgoing() {
       try {
          var size = dataWriter.measureString(data);
          countOfDataSent += size;
    
          dataWriter.writeString(data);
          dataWriter.storeAsync().done(function () {
             // Add a 1 second delay so the user can see what's going on.
             setTimeout(writeOutgoing, 1000);
          }, writeError);
       }
       catch (error) {
          displayStatus("Sync write error: " + getError(error));
       }
    }
    

3. 着信データの読み取り

このセクションのコードでは、WebSocket オブジェクトでサーバーからデータを読み取ります。

  readError() 関数については、この後の手順で定義します。

 

  • 次のコードを .js ファイルに追加して、readIncoming() 関数を定義します。

    
    function readIncoming(args) {
       // Buffer as much data as you require for your protocol.
       dataReader.loadAsync(100).done(function (sizeBytesRead) {
          countOfDataReceived += sizeBytesRead;
    
          var incomingBytes = new Array(sizeBytesRead);
          dataReader.readBytes(incomingBytes);
    
          // Do something with the data.
          // Alternatively you can use DataReader to read out individual booleans,
          // ints, strings, etc.
    
          // Start another read.
          readIncoming();
       }, readError);
    }
    

4. エラー処理コードの追加

  • 非同期ネットワーク メソッドの多くは、呼び出す場合、例外を処理するようにコードを記述する必要があります。エラーについてよく理解し、適切な判断ができるように、例外ハンドラーは例外の原因についての詳しい情報を取得できます。詳しくは、「ネットワーク アプリで例外を処理する方法」をご覧ください。

    コードを .js ファイルに追加して、書き込みと読み取りのエラーをログに記録 (または他のアクションを実行) する writeError() 関数と readError() 関数をそれぞれ定義します。具体的にどのようなコードを実装するかは、目的によって異なります。

    
    function writeError(error) {
       // Add your code to handle write errors.
    }
    
    function readError(error) {
       // Add your code to handle read errors.
    }
    

5. StreamWebSocket.Closed イベントに使うコールバックの登録

StreamWebSocket.Closed イベントが発生すると、登録したコールバックが呼び出されて、WebSocketClosedEventArgs からデータを受け取り、接続を閉じます。

  • 次のコードを .js ファイルに追加します。

    function onClosed(args) {
       // You can add code to log or display the code and reason
       // for the closure (stored in args.code and args.reason)
       if (streamWebSocket) {
          streamWebSocket.close();
       }
       streamWebSocket = null;
    }
    

要約と次のステップ

このチュートリアルでは、StreamWebSocket を使って、WebSocket サーバーに接続する方法と、データを送受信する方法について説明しました。

WebSocket を使ってデータを送受信する方法を紹介した詳しいデモについては、WebSocket のサンプルをご覧ください。

関連トピック

その他

promise を使った JavaScript での非同期プログラミングに関する記事

WebSocket を使った接続

JavaScript を使った初めての Windows ランタイム アプリの作成

MessageWebSocket を使って接続する方法

ネットワーク アプリで例外を処理する方法

ネットワーク機能を設定する方法

リファレンス

StreamWebSocket

Windows.Networking.Sockets

サンプル

WebSocket のサンプル