WebSocket-サーバーとの通信

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

サーバーが新しいデータが利用可能であることがわかった瞬間にクライアントにデータを送信できるようにするテクノロジーは、かなり前から存在しています。彼らは次のような名前で行きます"Push" または “Comet”

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

ソケットをWebに持ち込む

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

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

var connection = new WebSocket('ws://html5rocks.websocket.org/echo', ['soap', 'xmpp']);

wsWebSocket接続の新しいURLスキーマです。もありますwss、同じ方法で安全なWebSocket接続を行う https 安全なHTTP接続に使用されます。

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

2番目の引数はオプションを受け入れます subprotocols。文字列または文字列の配列にすることができます。各文字列は、subprotocol 名前とサーバーは、渡されたものの1つのみを受け入れます subprotocols配列内。承認済みsubprotocol 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接続を適切に処理できません。同時に多数の接続を開いたままにするには、低いパフォーマンスコストで高い同時実行性を受け取るアーキテクチャが必要です。