Websockets-communicating-server

提供:Dev Guides
移動先:案内検索

WebSockets-サーバーとの通信

Webは、主にHTTPの要求/応答パラダイムを中心に構築されています。 クライアントがWebページをロードすると、ユーザーが次のページをクリックするまで何も起こりません。 2005年頃、AJAXはWebをより動的に感じるようになりました。 それでも、すべてのHTTP通信はクライアントによって操作されます。これには、サーバーから新しいデータを読み込むためにユーザーの操作または定期的なポーリングが必要です。

新しいデータが利用可能であるとわかった瞬間にサーバーがクライアントにデータを送信できるようにする技術は、かなり前から存在していました。 "Push""Comet" などの名前で移動します。

  • ロングポーリング*では、クライアントはサーバーへのHTTP接続を開き、応答を送信するまでサーバーを開いたままにします。 サーバーが実際に新しいデータを取得するたびに、サーバーは応答を送信します。 長いポーリングと他のテクニックは非常にうまく機能します。 ただし、これらはすべて1つの問題を共有しており、HTTPのオーバーヘッドを運ぶため、低遅延アプリケーションにはあまり適していません。 たとえば、ブラウザのマルチプレイヤーシューティングゲームや、リアルタイムコンポーネントを備えた他のオンラインゲームです。

ソケットをWebに持ち込む

Web Socket仕様は、Webブラウザーとサーバー間の「ソケット」接続を確立するAPIを定義しています。 簡単に言えば、クライアントとサーバーの間に永続的な接続があり、両方の当事者はいつでもデータの送信を開始できます。

Webソケット接続は、コンストラクターを使用して簡単に開くことができます-

var connection = new WebSocket('ws://html5rocks.websocket.org/echo', ['soap', 'xmpp']);
*ws* は、WebSocket接続の新しいURLスキーマです。 *wss* もあります。これは、安全なHTTP接続に *https* が使用されるのと同じ方法で、安全なWebSocket接続用です。

一部のイベントハンドラを接続にすぐに接続すると、接続が開かれたとき、着信メッセージを受信したとき、またはエラーが発生したときを知ることができます。

2番目の引数は、オプションの subprotocols を受け入れます。 文字列または文字列の配列を指定できます。 各文字列は*サブプロトコル*名を表す必要があり、サーバーは配列で渡された*サブプロトコル*の1つのみを受け入れます。 受け入れられた*サブプロトコル*は、WebSocketオブジェクトのプロトコルプロパティにアクセスすることで決定できます。

//When the connection is open, send some data to the server
connection.onopen = function () {
   connection.send('Ping');//Send the message 'Ping' to the server
};

//Log errors
connection.onerror = function (error) {
   console.log('WebSocket Error ' + error);
};

//Log messages from the server
connection.onmessage = function (e) {
   console.log('Server: ' + e.data);
};

サーバーとの通信

サーバーへの接続が確立されると(openイベントが起動されると)、接続オブジェクトのsend(メッセージ)メソッドを使用してサーバーへのデータ送信を開始できます。 以前は文字列のみをサポートしていましたが、最新の仕様では、バイナリメッセージも送信できるようになりました。 バイナリデータを送信するには、BlobまたはArrayBufferオブジェクトが使用されます。

//Sending String
connection.send('your message');

//Sending canvas ImageData as ArrayBuffer
var img = canvas_context.getImageData(0, 0, 400, 320);
var binary = new Uint8Array(img.data.length);

for (var i = 0; i < img.data.length; i++) {
   binary[i] = img.data[i];
}

connection.send(binary.buffer);

//Sending file as Blob
var file = document.querySelector('input[type = "file"]').files[0];
connection.send(file);

同様に、サーバーはいつでもメッセージを送信する場合があります。 これが発生するたびに、onmessageコールバックが起動します。 コールバックはイベントオブジェクトを受け取り、実際のメッセージは `+ data +`プロパティを介してアクセスできます。

WebSocketは、最新の仕様のバイナリメッセージも受信できます。 バイナリフレームは、BlobまたはArrayBuffer形式で受信できます。 受信したバイナリの形式を指定するには、WebSocketオブジェクトのbinaryTypeプロパティを「blob」または「arraybuffer」に設定します。 デフォルトの形式は「blob」です。

//Setting binaryType to accept received binary as either 'blob' or 'arraybuffer'
connection.binaryType = 'arraybuffer';
connection.onmessage = function(e) {
   console.log(e.data.byteLength);//ArrayBuffer object if binary
};

WebSocketに新しく追加されたもう1つの機能は拡張機能です。 拡張機能を使用すると、圧縮、多重化などのフレームを送信できます。

//Determining accepted extensions
console.log(connection.extensions);

クロスオリジンコミュニケーション

最新のプロトコルであるため、クロスオリジン通信はWebSocketに直接組み込まれています。 WebSocketは、任意のドメインの関係者間の通信を可能にします。 サーバーは、そのサービスをすべてのクライアントで利用可能にするか、明確に定義されたドメインのセットに存在するクライアントのみで利用可能にするかを決定します。

プロキシサーバー

すべての新しいテクノロジーには、新しい一連の問題が伴います。 WebSocketの場合、ほとんどの企業ネットワークでHTTP接続を仲介するプロキシサーバーとの互換性です。 WebSocketプロトコルは、HTTPアップグレードシステム(通常はHTTP/SSLに使用されます)を使用して、HTTP接続をWebSocket接続に「アップグレード」します。 一部のプロキシサーバーはこれを好まないため、接続を切断します。 したがって、特定のクライアントがWebSocketプロトコルを使用していても、接続を確立できない場合があります。 これにより、次のセクションがさらに重要になります:)

サーバー側

WebSocketを使用すると、サーバー側アプリケーションのまったく新しい使用パターンが作成されます。 LAMPなどの従来のサーバースタックは、HTTP要求/応答サイクルを中心に設計されていますが、多くの場合、開いている多数のWebSocket接続をうまく処理できません。 同時に多数の接続を開いたままにするには、低いパフォーマンスコストで高い同時実行性を受け取るアーキテクチャが必要です。