WebSocket-クイックガイド
文字通り、ハンドシェイクは、挨拶、お祝い、同意、または別れを象徴するように、2人の個人が右手を握って振ることと定義できます。コンピュータサイエンスでは、ハンドシェイクはサーバーがクライアントと同期していることを確認するプロセスです。ハンドシェイクは、WebSocketプロトコルの基本的な概念です。
次の図は、さまざまなクライアントとのサーバーハンドシェイクを示しています-
Webソケット–定義
Webソケットは、サーバーとクライアント間の双方向通信として定義されます。つまり、両方の当事者が同時に通信し、データを交換します。
WebSocketの要点は true concurrency そして optimization of performance、より応答性が高く、リッチなWebアプリケーションになります。
Webソケットプロトコルの説明
このプロトコルは、ゼロからの全二重通信を定義します。Webソケットは、デスクトップの豊富な機能をWebブラウザーにもたらすための一歩を踏み出しました。これは、クライアント/サーバーWebテクノロジーで長い間待ち望まれていた進化を表しています。
Webソケットの主な機能は次のとおりです-
Webソケットプロトコルは標準化されています。つまり、このプロトコルを使用すると、Webサーバーとクライアント間のリアルタイム通信が可能になります。
Webソケットは、クライアントとサーバー間のリアルタイム通信のためのクロスプラットフォーム標準に変わりつつあります。
この規格は、新しい種類のアプリケーションを可能にします。リアルタイムWebアプリケーションのビジネスは、このテクノロジーの助けを借りてスピードアップできます。
Web Socketの最大の利点は、単一のTCP接続を介して双方向通信(全二重)を提供することです。
URL
HTTPには、httpやhttpsなどの独自のスキーマセットがあります。Webソケットプロトコルにも、URLパターンで定義された同様のスキーマがあります。
次の画像は、トークンでのWeb SocketURLを示しています。
ブラウザのサポート
WebSocketプロトコルの最新の仕様は次のように定義されています。 RFC 6455 –提案された標準。
RFC 6455 Internet Explorer、Mozilla Firefox、Google Chrome、Safari、Operaなどのさまざまなブラウザでサポートされています。
Webソケットの必要性に飛び込む前に、に使用されている既存の手法を確認する必要があります。 duplex communicationサーバーとクライアントの間。それらは次のとおりです-
- Polling
- ロングポーリング
- Streaming
- ポストバックとAJAX
- HTML5
ポーリング
ポーリングは、送信に存在するデータに関係なく定期的な要求を実行する方法として定義できます。定期的なリクエストは同期的に送信されます。クライアントは、指定された時間間隔でサーバーに定期的に要求を行います。サーバーの応答には、使用可能なデータまたは警告メッセージが含まれています。
ロングポーリング
ロングポーリングには、その名前が示すように、ポーリングと同様の手法が含まれます。クライアントとサーバーは、データがフェッチされるかタイムアウトが発生するまで、接続をアクティブに保ちます。何らかの理由で接続が失われた場合、クライアントは最初からやり直して順次要求を実行できます。
長いポーリングは、ポーリングプロセスよりもパフォーマンスが向上するだけですが、リクエストが頻繁に発生すると、プロセスが遅くなる可能性があります。
ストリーミング
これは、リアルタイムのデータ送信に最適なオプションと見なされています。サーバーは、必要なデータがフェッチされるまで、クライアントとの接続を開いたままアクティブに保ちます。この場合、接続は無期限に開いていると言われます。ストリーミングにはHTTPヘッダーが含まれているため、ファイルサイズが大きくなり、遅延が大きくなります。これは大きな欠点と見なすことができます。
AJAX
AJAXはJavascriptに基づいています XmlHttpRequestオブジェクト。これは、非同期JavascriptおよびXMLの省略形です。XmlHttpRequestオブジェクトを使用すると、Webページ全体をリロードせずにJavascriptを実行できます。AJAXは、Webページの一部のみを送受信します。
AJAX呼び出しのコードスニペット XmlHttpRequest オブジェクトは次のとおりです-
var xhttp;
if (window.XMLHttpRequest) {
xhttp = new XMLHttpRequest();
} else {
// code for IE6, IE5
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
の主な欠点 AJAX と比較して Web Sockets は−
- HTTPヘッダーを送信するため、合計サイズが大きくなります。
- 通信は半二重です。
- Webサーバーはより多くのリソースを消費します。
HTML5
HTML5は、Webアプリケーションを開発および設計するための堅牢なフレームワークです。主な柱は次のとおりです。Mark-up, CSS3 そして Javascript 一緒にAPI。
次の図は、HTML5コンポーネントを示しています-
以下に示すコードスニペットは、HTML5とそのDoctypeの宣言について説明しています。
<!DOCTYPE html>
なぜWebソケットが必要なのですか?
インターネットは、情報の概念的なWebを形成するために相互にリンクするハイパーテキストマークアップ言語(HTML)ページのコレクションであると考えられていました。時間の経過とともに、静的リソースの数が増え、画像などのアイテムが豊富になり、Webファブリックの一部になり始めました。
動的サーバーページ(クエリに基づいてコンテンツが生成されたページ)を可能にする高度なサーバーテクノロジー。
間もなく、より動的なWebページが必要になるため、ダイナミックハイパーテキストマークアップ言語(DHTML)が利用できるようになります。JavaScriptに感謝します。その後の数年間で、私たちは見ましたcross frame communication ページのリロードとそれに続く回避を回避するために HTTP Polling フレーム内。
ただし、これらのソリューションはいずれも、サーバーとクライアント間のリアルタイムの双方向通信に対して真に標準化されたクロスブラウザーソリューションを提供していませんでした。
これにより、WebSocketsプロトコルが必要になりました。これにより、全二重通信が実現し、デスクトップが豊富な機能がすべてのWebブラウザーにもたらされました。
Web Socketは、Web通信の歴史における主要なアップグレードを表しています。それが存在する前は、Webクライアントとサーバー間のすべての通信はHTTPのみに依存していました。
Web Socketは、永続的な全二重である接続の動的フローに役立ちます。全二重とは、両端からかなり高速な通信を指します。
これは、既存のプロトコルのすべての欠点を克服する効率性から、ゲームチェンジャーと呼ばれています。
開発者とアーキテクトのためのWebSocket
開発者とアーキテクトにとってのWebSocketの重要性-
Web Socketは独立したTCPベースのプロトコルですが、従来は純粋なTCP接続上でのみ実行される他のプロトコルをサポートするように設計されています。
Web Socketは、他のプロトコルを実行できるトランスポート層です。Web Socket APIは、特定のプロトコルを解釈できるプロトコルライブラリであるサブプロトコルを定義する機能をサポートしています。
このようなプロトコルの例には、XMPP、STOMP、およびAMQPが含まれます。開発者は、HTTP要求/応答パラダイムの観点から考える必要がなくなりました。
ブラウザ側の唯一の要件は、Web Socketハンドシェイクを解釈し、Web Socket接続を確立および維持できるJavaScriptライブラリを実行することです。
サーバー側では、業界標準は、TCP上で実行され、Web SocketGatewayを活用する既存のプロトコルライブラリを使用することです。
次の図は、Webソケットの機能を説明しています-
WebSocket接続はHTTP経由で開始されます。HTTPサーバーは通常、WebSocketハンドシェイクをアップグレード要求として解釈します。
Web Socketsは、既存のHTTP環境を補完するアドオンであり、Web機能を追加するために必要なインフラストラクチャを提供できます。これは、クライアントとサーバー間でデータが双方向に流れることを可能にする、より高度な全二重プロトコルに依存しています。
Webソケットの機能
Web Socketsは、Webサーバーとクライアント間の接続を提供し、両方の当事者がデータの送信を開始できるようにします。
WebSocketの接続を確立する手順は次のとおりです。
クライアントは、WebSocketハンドシェイクと呼ばれるプロセスを介して接続を確立します。
このプロセスは、クライアントが通常のHTTPリクエストをサーバーに送信することから始まります。
アップグレードヘッダーが要求されます。このリクエストでは、リクエストがWebSocket接続用であることをサーバーに通知します。
Web SocketURLは wsスキーム。これらは、HTTPと同等の安全なWebソケット接続にも使用されます。
初期リクエストヘッダーの簡単な例は次のとおりです。
GET ws://websocket.example.com/ HTTP/1.1
Origin: http://example.com
Connection: Upgrade
Host: websocket.example.com
Upgrade: websocket
Web Socketsは、Webだけでなく、モバイル業界でも重要な役割を果たします。WebSocketsの重要性を以下に示します。
名前が示すように、WebSocketはWebに関連しています。Webは、一部のブラウザー向けの一連の手法で構成されています。これは、デスクトップコンピュータ、ラップトップ、タブレット、スマートフォンなど、膨大な数のデバイス向けの幅広い通信プラットフォームです。
Web Socketsを利用するHTML5アプリは、HTML5対応のWebブラウザーで動作します。
Webソケットは、主流のオペレーティングシステムでサポートされています。モバイル業界のすべての主要プレーヤーは、独自のネイティブアプリでWeb SocketAPIを提供しています。
Webソケットは全二重通信と呼ばれます。Web Socketsのアプローチは、クライアントとサーバーからの更新が同時に共有されるチャットルームなどの特定のカテゴリのWebアプリケーションに適しています。
HTML5仕様の一部であるWebSocketsは、Webページとリモートホスト間の全二重通信を可能にします。このプロトコルは、次の利点を実現するように設計されています。これらは重要なポイントと見なすことができます。
Reduce unnecessary network traffic and latency (2つではなく)1つの接続で全二重を使用します。
Streaming through proxies and firewalls、アップストリームとダウンストリームの通信を同時にサポートします。
それらの間の通信のために、クライアントからサーバーへの接続を初期化する必要があります。接続を初期化するには、リモートサーバーまたはローカルサーバーのURLを使用してJavascriptオブジェクトを作成する必要があります。
var socket = new WebSocket(“ ws://echo.websocket.org ”);
上記のURLは、テストや実験に使用できるパブリックアドレスです。websocket.orgサーバーは常に稼働しており、メッセージを受信してクライアントに送り返すとき。
これは、アプリケーションが正しく機能することを保証するための最も重要なステップです。
Webソケット–イベント
4つの主要なWebSocketAPIがあります events −
- Open
- Message
- Close
- Error
各イベントは、次のような機能を実装することによって処理されます onopen, onmessage、 onclose そして onerrorそれぞれ機能します。addEventListenerメソッドを使用して実装することもできます。
イベントと機能の概要は次のとおりです。
開いた
クライアントとサーバーの間で接続が確立されると、WebSocketインスタンスからopenイベントが発生します。これは、クライアントとサーバー間の初期ハンドシェイクと呼ばれます。接続が確立されると発生するイベントが呼び出されますonopen。
メッセージ
メッセージイベントは通常、サーバーがデータを送信したときに発生します。サーバーからクライアントに送信されるメッセージには、プレーンテキストメッセージ、バイナリデータ、または画像を含めることができます。データが送信されるたびに、onmessage 関数が起動されます。
閉じる
Closeイベントは、サーバーとクライアント間の通信の終了を示します。接続を閉じることはの助けを借りて可能ですoncloseイベント。の助けを借りて通信の終わりをマークした後oncloseイベントの場合、サーバーとクライアント間でメッセージをそれ以上転送することはできません。接続が不十分なため、イベントが終了する可能性もあります。
エラー
通信中に発生する何らかの間違いのエラーマーク。それはの助けを借りてマークされていますonerror イベント。 Onerror常に接続が終了します。すべてのイベントの詳細な説明については、以降の章で説明します。
Webソケット–アクション
イベントは通常、何かが起こったときにトリガーされます。一方、ユーザーが何かをしたいときにアクションが実行されます。アクションは、ユーザーによる関数を使用した明示的な呼び出しによって行われます。
Web Socketプロトコルは、2つの主要なアクションをサポートします。
- send()
- close()
送信()
このアクションは通常、テキストファイル、バイナリデータ、または画像を含むメッセージの送信を含む、サーバーとの通信に適しています。
send()アクションを使用して送信されるチャットメッセージは次のとおりです。
// get text view and button for submitting the message
var textsend = document.getElementById(“text-view”);
var submitMsg = document.getElementById(“tsend-button”);
//Handling the click event
submitMsg.onclick = function ( ) {
// Send the data
socket.send( textsend.value);
}
Note −メッセージの送信は、接続が開いている場合にのみ可能です。
閉じる()
この方法は、さようならハンドシェイクの略です。接続を完全に終了し、接続が再確立されるまでデータを転送できません。
var textsend = document.getElementById(“text-view”);
var buttonStop = document.getElementById(“stop-button”);
//Handling the click event
buttonStop.onclick = function ( ) {
// Close the connection if open
if (socket.readyState === WebSocket.OPEN){
socket.close( );
}
}
次のコードスニペットを使用して、意図的に接続を閉じることもできます-
socket.close(1000,”Deliberate Connection”);
クライアントとサーバーの間に接続が確立されると、WebSocketインスタンスからopenイベントが発生します。これは、クライアントとサーバー間の初期ハンドシェイクと呼ばれます。
接続が確立されると発生するイベントは、 onopen。WebSocket接続の作成は本当に簡単です。あなたがしなければならないのはWebSocket constructor サーバーのURLを渡します。
次のコードは、WebSocket接続を作成するために使用されます-
// Create a new WebSocket.
var socket = new WebSocket('ws://echo.websocket.org');
接続が確立されると、WebSocketインスタンスでopenイベントが発生します。
onopen クライアントとサーバー間の最初のハンドシェイクを指します。これは最初の取引につながり、Webアプリケーションはデータを送信する準備ができています。
次のコードスニペットは、WebSocketプロトコルの接続を開くことを説明しています-
socket.onopen = function(event) {
console.log(“Connection established”);
// Display user friendly messages for the successful establishment of connection
var.label = document.getElementById(“status”);
label.innerHTML = ”Connection established”;
}
WebSocket接続が確立されるのを待っているユーザーに適切なフィードバックを提供することをお勧めします。ただし、WebSocket接続は比較的高速であることに常に注意してください。
確立されたWebSocket接続のデモは、指定されたURLに記載されています- https://www.websocket.org/echo.html
接続の確立とユーザーへの応答のスナップショットを以下に示します-
オープン状態を確立すると、接続が終了するまで全二重通信とメッセージの転送が可能になります。
例
クライアントの構築-HTML5ファイル。
<!DOCTYPE html>
<html>
<meta charset = "utf-8" />
<title>WebSocket Test</title>
<script language = "javascript" type = "text/javascript">
var wsUri = "ws://echo.websocket.org/";
var output;
function init() {
output = document.getElementById("output");
testWebSocket();
}
function testWebSocket() {
websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) {
onOpen(evt)
};
}
function onOpen(evt) {
writeToScreen("CONNECTED");
}
window.addEventListener("load", init, false);
</script>
<h2>WebSocket Test</h2>
<div id = "output"></div>
</html>
出力は次のようになります-
上記のHTML5およびJavaScriptファイルは、WebSocketの2つのイベントの実装を示しています。
onLoad これは、JavaScriptオブジェクトの作成と接続の初期化に役立ちます。
onOpen サーバーとの接続を確立し、ステータスを送信します。
クライアントとサーバーの間に接続が確立されると、 openイベントはWebSocketインスタンスから発生します。通信中に発生するミスによりエラーが発生します。それはの助けを借りてマークされていますonerror イベント。 Onerror 常に接続が終了します。
ザ・ onerror通信間で問題が発生すると、イベントが発生します。行事onerror その後に接続終了が続きます。 close イベント。
予期しないエラーについて常にユーザーに通知し、再接続を試みることをお勧めします。
socket.onclose = function(event) {
console.log("Error occurred.");
// Inform the user about the error.
var label = document.getElementById("status-label");
label.innerHTML = "Error: " + event;
}
エラー処理に関しては、内部パラメータと外部パラメータの両方を考慮する必要があります。
内部パラメーターには、コードのバグや予期しないユーザーの動作が原因で生成される可能性のあるエラーが含まれます。
外部エラーはアプリケーションとは何の関係もありません。むしろ、それらは制御できないパラメータに関連しています。最も重要なのはネットワーク接続です。
インタラクティブな双方向Webアプリケーションには、アクティブなインターネット接続が必要です。
ネットワークの可用性の確認
タスクの途中で突然ネットワーク接続が応答しなくなったときに、ユーザーがWebアプリを楽しんでいると想像してみてください。最新のネイティブデスクトップおよびモバイルアプリケーションでは、ネットワークの可用性を確認するのが一般的なタスクです。
これを行う最も一般的な方法は、稼働しているはずのWebサイト(たとえば、http://www.google.com)にHTTPリクエストを送信することです。要求が成功すると、デスクトップまたはモバイルデバイスはアクティブな接続があることを認識します。同様に、HTMLにはXMLHttpRequest ネットワークの可用性を判断するため。
ただし、HTML5を使用するとさらに簡単になり、ブラウザーがWeb応答を受け入れることができるかどうかを確認する方法が導入されました。これは、ナビゲーターオブジェクトを介して実現されます-
if (navigator.onLine) {
alert("You are Online");
}else {
alert("You are Offline");
}
オフラインモードとは、デバイスが接続されていないか、ユーザーがブラウザのツールバーからオフラインモードを選択したことを意味します。
ネットワークが利用できないことをユーザーに通知し、WebSocketのクローズイベントが発生したときに再接続を試みる方法は次のとおりです-
socket.onclose = function (event) {
// Connection closed.
// Firstly, check the reason.
if (event.code != 1000) {
// Error code 1000 means that the connection was closed normally.
// Try to reconnect.
if (!navigator.onLine) {
alert("You are offline. Please connect to the Internet and try again.");
}
}
}
エラーメッセージを受信するためのデモ
次のプログラムは、WebSocketを使用してエラーメッセージを表示する方法を説明しています-
<!DOCTYPE html>
<html>
<meta charset = "utf-8" />
<title>WebSocket Test</title>
<script language = "javascript" type = "text/javascript">
var wsUri = "ws://echo.websocket.org/";
var output;
function init() {
output = document.getElementById("output");
testWebSocket();
}
function testWebSocket() {
websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) {
onOpen(evt)
};
websocket.onclose = function(evt) {
onClose(evt)
};
websocket.onerror = function(evt) {
onError(evt)
};
}
function onOpen(evt) {
writeToScreen("CONNECTED");
doSend("WebSocket rocks");
}
function onClose(evt) {
writeToScreen("DISCONNECTED");
}
function onError(evt) {
writeToScreen('<span style = "color: red;">ERROR:</span> ' + evt.data);
}
function doSend(message) {
writeToScreen("SENT: " + message); websocket.send(message);
}
function writeToScreen(message) {
var pre = document.createElement("p");
pre.style.wordWrap = "break-word";
pre.innerHTML = message; output.appendChild(pre);
}
window.addEventListener("load", init, false);
</script>
<h2>WebSocket Test</h2>
<div id = "output"></div>
</html>
出力は次のとおりです-
ザ・ Messageイベントは通常、サーバーがデータを送信するときに発生します。サーバーからクライアントに送信されるメッセージには、プレーンテキストメッセージ、バイナリデータ、または画像を含めることができます。データが送信されるたびに、onmessage 関数が起動されます。
このイベントは、サーバーに対するクライアントの耳として機能します。サーバーがデータを送信するときはいつでも、onmessage イベントが発生します。
次のコードスニペットは、WebSocketプロトコルの接続を開くことを説明しています。
connection.onmessage = function(e){
var server_message = e.data;
console.log(server_message);
}
また、WebSocketを使用して転送できるデータの種類を考慮する必要があります。Webソケットプロトコルは、テキストおよびバイナリデータをサポートします。Javascriptに関しては、text は文字列と呼ばれ、バイナリデータは次のように表されます。 ArrayBuffer。
Webソケットは、一度に1つのバイナリ形式のみをサポートします。バイナリデータの宣言は、次のように明示的に行われます。
socket.binaryType = ”arrayBuffer”;
socket.binaryType = ”blob”;
文字列
文字列は、XMLやJSONなどの人間が読める形式を処理するのに役立つと考えられています。いつでもonmessage イベントが発生した場合、クライアントはデータ型を確認し、それに応じて行動する必要があります。
文字列としてデータ型を決定するためのコードスニペットを以下に示します-
socket.onmessage = function(event){
if(typeOf event.data === String ) {
console.log(“Received data string”);
}
}
JSON(JavaScriptオブジェクト表記)
これは、コンピュータ間で人間が読めるデータを転送するための軽量フォーマットです。JSONの構造は、キーと値のペアで構成されています。
例
{
name: “James Devilson”,
message: “Hello World!”
}
次のコードは、JSONオブジェクトを処理してそのプロパティを抽出する方法を示しています-
socket.onmessage = function(event) {
if(typeOf event.data === String ){
//create a JSON object
var jsonObject = JSON.parse(event.data);
var username = jsonObject.name;
var message = jsonObject.message;
console.log(“Received data string”);
}
}
XML
XMLでの解析は難しくありませんが、テクニックはブラウザーごとに異なります。最良の方法は、jQueryなどのサードパーティライブラリを使用して解析することです。
XMLとJSONの両方で、サーバーは文字列として応答し、クライアント側で解析されます。
ArrayBuffer
構造化されたバイナリデータで構成されています。同封のビットは、位置を簡単に追跡できるように順番に並べられています。ArrayBuffersは、画像ファイルを保存するのに便利です。
ArrayBuffersを使用してデータを受信するのは非常に簡単です。オペレーターinstanceOf 等しい演算子の代わりに使用されます。
次のコードは、ArrayBufferオブジェクトを処理および受信する方法を示しています-
socket.onmessage = function(event) {
if(event.data instanceof ArrayBuffer ){
var buffer = event.data;
console.log(“Received arraybuffer”);
}
}
デモアプリケーション
次のプログラムコードは、WebSocketを使用してメッセージを送受信する方法を示しています。
<!DOCTYPE html>
<html>
<meta charset = "utf-8" />
<title>WebSocket Test</title>
<script language = "javascript" type = "text/javascript">
var wsUri = "ws://echo.websocket.org/";
var output;
function init() {
output = document.getElementById("output");
testWebSocket();
}
function testWebSocket() {
websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) {
onOpen(evt)
};
websocket.onmessage = function(evt) {
onMessage(evt)
};
websocket.onerror = function(evt) {
onError(evt)
};
}
function onOpen(evt) {
writeToScreen("CONNECTED");
doSend("WebSocket rocks");
}
function onMessage(evt) {
writeToScreen('<span style = "color: blue;">RESPONSE: ' +
evt.data+'</span>'); websocket.close();
}
function onError(evt) {
writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
}
function doSend(message) {
writeToScreen("SENT: " + message); websocket.send(message);
}
function writeToScreen(message) {
var pre = document.createElement("p");
pre.style.wordWrap = "break-word";
pre.innerHTML = message; output.appendChild(pre);
}
window.addEventListener("load", init, false);
</script>
<h2>WebSocket Test</h2>
<div id = "output"></div>
</html>
出力を以下に示します。
Closeイベントは、サーバーとクライアント間の通信の終了を示します。接続を閉じることはの助けを借りて可能ですoncloseイベント。の助けを借りて通信の終わりをマークした後oncloseイベントの場合、サーバーとクライアント間でメッセージをそれ以上転送することはできません。接続が不十分なため、イベントの終了も発生する可能性があります。
ザ・ close() メソッドはの略です goodbye handshake。接続を終了し、接続を再開しない限りデータを交換できません。
前の例と同様に、 close() ユーザーが2番目のボタンをクリックしたときのメソッド。
var textView = document.getElementById("text-view");
var buttonStop = document.getElementById("stop-button");
buttonStop.onclick = function() {
// Close the connection, if open.
if (socket.readyState === WebSocket.OPEN) {
socket.close();
}
}
以下に示すように、前述のコードと理由のパラメーターを渡すこともできます。
socket.close(1000, "Deliberate disconnection");
次のコードは、WebSocket接続を閉じるまたは切断する方法の完全な概要を示しています-
<!DOCTYPE html>
<html>
<meta charset = "utf-8" />
<title>WebSocket Test</title>
<script language = "javascript" type = "text/javascript">
var wsUri = "ws://echo.websocket.org/";
var output;
function init() {
output = document.getElementById("output");
testWebSocket();
}
function testWebSocket() {
websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) {
onOpen(evt)
};
websocket.onclose = function(evt) {
onClose(evt)
};
websocket.onmessage = function(evt) {
onMessage(evt)
};
websocket.onerror = function(evt) {
onError(evt)
};
}
function onOpen(evt) {
writeToScreen("CONNECTED");
doSend("WebSocket rocks");
}
function onClose(evt) {
writeToScreen("DISCONNECTED");
}
function onMessage(evt) {
writeToScreen('<span style = "color: blue;">RESPONSE: ' +
evt.data+'</span>'); websocket.close();
}
function onError(evt) {
writeToScreen('<span style = "color: red;">ERROR:</span> '
+ evt.data);
}
function doSend(message) {
writeToScreen("SENT: " + message); websocket.send(message);
}
function writeToScreen(message) {
var pre = document.createElement("p");
pre.style.wordWrap = "break-word";
pre.innerHTML = message;
output.appendChild(pre);
}
window.addEventListener("load", init, false);
</script>
<h2>WebSocket Test</h2>
<div id = "output"></div>
</html>
出力は次のとおりです-
Web Socketサーバーは単純なプログラムであり、WebSocketのイベントとアクションを処理する機能があります。通常、同様のメソッドをWeb SocketクライアントAPIに公開し、ほとんどのプログラミング言語が実装を提供します。次の図は、WebSocketサーバーとWebSocketクライアント間の通信プロセスを示しており、トリガーされたイベントとアクションを強調しています。
次の図は、WebSocketサーバーとクライアントイベントのトリガーを示しています-
Webサーバーへの接続
Web Socketサーバーは、WebSocketクライアントと同じように機能します。イベントに応答し、必要に応じてアクションを実行します。使用するプログラミング言語に関係なく、すべてのWebSocketサーバーは特定のアクションを実行します。
WebSocketアドレスに初期化されます。それは処理しますOnOpen, OnClose, そして OnMessage イベント、およびクライアントにもメッセージを送信します。
Webソケットサーバーインスタンスの作成
すべてのWebSocketサーバーには、有効なホストとポートが必要です。サーバーでWebSocketインスタンスを作成する例は次のとおりです。
var server = new WebSocketServer("ws://localhost:8181");
以前は使用されていなかったポートを指定して、有効なURLを使用できます。接続されたクライアントの記録を保持すると、さまざまなデータの詳細が提供されたり、各クライアントにさまざまなメッセージが送信されたりするため、非常に便利です。
フレックは、着信接続(クライアント)を表します IwebSocketConnectionインターフェース。誰かが私たちのサービスに接続または切断するときはいつでも、空のリストを作成または更新することができます。
var clients = new List<IWebSocketConnection>();
その後、私たちは呼び出すことができます Startメソッドを実行し、クライアントが接続するのを待ちます。起動後、サーバーは着信接続を受け入れることができます。Fleckでは、Startメソッドには、イベントを発生させたソケットを示すパラメーターが必要です-
server.Start(socket) =>
{
});
OnOpenイベント
ザ・ OnOpenイベントは、新しいクライアントがアクセスを要求したことを判別し、最初のハンドシェイクを実行します。クライアントをリストに追加し、おそらくIPアドレスなどのクライアントに関連する情報を保存する必要があります。Fleckは、そのような情報と、接続の一意の識別子を提供します。
server.Start(socket) ⇒ {
socket.OnOpen = () ⇒ {
// Add the incoming connection to our list.
clients.Add(socket);
}
// Handle the other events here...
});
OnCloseイベント
ザ・ OnCloseクライアントが切断されるたびにイベントが発生します。クライアントはリストから削除され、残りのクライアントに切断について通知します。
socket.OnClose = () ⇒ {
// Remove the disconnected client from the list.
clients.Remove(socket);
};
OnMessageイベント
ザ・ OnMessageクライアントがサーバーにデータを送信すると、イベントが発生します。このイベントハンドラー内で、着信メッセージをクライアントに送信することも、クライアントの一部のみを選択することもできます。
プロセスは簡単です。このハンドラーは、という名前の文字列を受け取ることに注意してくださいmessage パラメータとして-
socket.OnMessage = () ⇒ {
// Display the message on the console.
Console.WriteLine(message);
};
Send()メソッド
ザ・ Send()メソッドは、指定されたクライアントに目的のメッセージを送信するだけです。Send()を使用すると、テキストまたはバイナリデータをクライアント間で保存できます。
の働き OnMessage イベントは以下の通りです−
socket.OnMessage = () ⇒ {
foreach (var client in clients) {
// Send the message to everyone!
// Also, send the client connection's unique identifier in order
// to recognize who is who.
client.Send(client.ConnectionInfo.Id + " says: " + message);
}
};
API –定義
API(Application Program Interfaceの略)は、ソフトウェアアプリケーションを構築するためのルーチン、プロトコル、およびツールのセットです。
いくつかの重要な機能は次のとおりです。
APIは、ソフトウェアコンポーネントがどのように相互作用するかを指定し、グラフィカルユーザーインターフェイス(GUI)コンポーネントをプログラミングするときにAPIを使用する必要があります。
優れたAPIは、すべての構成要素を提供することにより、プログラムの開発を容易にします。
通常HTTP上で実行されるRESTは、モバイルアプリケーション、ソーシャルWebサイト、マッシュアップツール、および自動化されたビジネスプロセスでよく使用されます。
RESTスタイルは、限られた数の操作(動詞)を持つことによって、クライアントとサービス間の相互作用が強化されることを強調しています。
柔軟性は、リソースを割り当てることによって提供されます。独自のUniversalResource Identifier(URI)。
各動詞には特定の意味(GET、POST、PUT、およびDELETE)があるため、RESTはあいまいさを回避します。
WebSocketの利点
Web Socketは、REST、または一般的なHTTPに関するいくつかの問題を解決します-
双方向
HTTPは、クライアントが常に要求を開始する単方向プロトコルです。サーバーは応答を処理して返し、クライアントはそれを消費します。Web Socketは、要求/応答などの事前定義されたメッセージパターンがない双方向プロトコルです。クライアントまたはサーバーのいずれかが相手にメッセージを送信できます。
全二重
HTTPを使用すると、要求メッセージがクライアントからサーバーに送信され、サーバーが応答メッセージをクライアントに送信します。ある時点で、クライアントがサーバーと通信しているか、サーバーがクライアントと通信しています。Web Socketを使用すると、クライアントとサーバーは互いに独立して通信できます。
単一のTCP接続
通常、新しいTCP接続はHTTP要求に対して開始され、応答の受信後に終了します。別のHTTP要求/応答のために、新しいTCP接続を確立する必要があります。Web Socketの場合、HTTP接続は標準のHTTPアップグレードメカニズムを使用してアップグレードされ、クライアントとサーバーはWebSocket接続のライフサイクルの間同じTCP接続を介して通信します。
以下のグラフは、一定のペイロードサイズでN個のメッセージを処理するのにかかる時間(ミリ秒単位)を示しています。
これがこのグラフにフィードする生データです-
上記のグラフと表は、RESTオーバーヘッドがメッセージの数とともに増加することを示しています。これは、多くのTCP接続を開始および終了する必要があり、多くのHTTPヘッダーを送受信する必要があるためです。
最後の列は、REST要求を満たすための時間の乗算係数を特に示しています。
2番目のグラフは、ペイロードサイズを変更して、固定数のメッセージを処理するのにかかる時間を示しています。
これがこのグラフにフィードする生データです-
このグラフは、RESTエンドポイントの要求/応答を処理するための増分コストが最小限であり、ほとんどの時間が接続の開始/終了とHTTPセマンティクスの尊重に費やされていることを示しています。
結論
WebSocketは低レベルのプロトコルです。単純な要求/応答のデザインパターン、必要なリソースの作成/更新/削除の方法、その上に構築されるステータスコードなどを含むすべて。これらはすべてHTTP用に明確に定義されています。
Web Socketはステートフルプロトコルですが、HTTPはステートレスプロトコルです。Web Socket接続は単一のサーバーで垂直方向に拡張できますが、HTTPは水平方向に拡張できます。Web Socketの水平スケーリングには独自のソリューションがいくつかありますが、それらは標準に基づいていません。HTTPには、キャッシング、ルーティング、多重化など、他にも多くの機能があります。これらはすべて、WebSocketの上で定義する必要があります。
次のプログラムコードは、JavaScriptとWebSocketプロトコルを使用したチャットアプリケーションの動作を説明しています。
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = utf-8>
<title>HTML5 Chat</title>
<body>
<section id = "wrapper">
<header>
<h1>HTML5 Chat</h1>
</header>
<style>
#chat { width: 97%; }
.message { font-weight: bold; }
.message:before { content: ' '; color: #bbb; font-size: 14px; }
#log {
overflow: auto;
max-height: 300px;
list-style: none;
padding: 0;
}
#log li {
border-top: 1px solid #ccc;
margin: 0;
padding: 10px 0;
}
body {
font: normal 16px/20px "Helvetica Neue", Helvetica, sans-serif;
background: rgb(237, 237, 236);
margin: 0;
margin-top: 40px;
padding: 0;
}
section, header {
display: block;
}
#wrapper {
width: 600px;
margin: 0 auto;
background: #fff;
border-radius: 10px;
border-top: 1px solid #fff;
padding-bottom: 16px;
}
h1 {
padding-top: 10px;
}
h2 {
font-size: 100%;
font-style: italic;
}
header, article > * {
margin: 20px;
}
#status {
padding: 5px;
color: #fff;
background: #ccc;
}
#status.fail {
background: #c00;
}
#status.success {
background: #0c0;
}
#status.offline {
background: #c00;
}
#status.online {
background: #0c0;
}
#html5badge {
margin-left: -30px;
border: 0;
}
#html5badge img {
border: 0;
}
</style>
<article>
<form onsubmit = "addMessage(); return false;">
<input type = "text" id = "chat" placeholder = "type and press
enter to chat" />
</form>
<p id = "status">Not connected</p>
<p>Users connected: <span id = "connected">0
</span></p>
<ul id = "log"></ul>
</article>
<script>
connected = document.getElementById("connected");
log = document.getElementById("log");
chat = document.getElementById("chat");
form = chat.form;
state = document.getElementById("status");
if (window.WebSocket === undefined) {
state.innerHTML = "sockets not supported";
state.className = "fail";
}else {
if (typeof String.prototype.startsWith != "function") {
String.prototype.startsWith = function (str) {
return this.indexOf(str) == 0;
};
}
window.addEventListener("load", onLoad, false);
}
function onLoad() {
var wsUri = "ws://127.0.0.1:7777";
websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) { onOpen(evt) };
websocket.onclose = function(evt) { onClose(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
websocket.onerror = function(evt) { onError(evt) };
}
function onOpen(evt) {
state.className = "success";
state.innerHTML = "Connected to server";
}
function onClose(evt) {
state.className = "fail";
state.innerHTML = "Not connected";
connected.innerHTML = "0";
}
function onMessage(evt) {
// There are two types of messages:
// 1. a chat participant message itself
// 2. a message with a number of connected chat participants
var message = evt.data;
if (message.startsWith("log:")) {
message = message.slice("log:".length);
log.innerHTML = '<li class = "message">' +
message + "</li>" + log.innerHTML;
}else if (message.startsWith("connected:")) {
message = message.slice("connected:".length);
connected.innerHTML = message;
}
}
function onError(evt) {
state.className = "fail";
state.innerHTML = "Communication error";
}
function addMessage() {
var message = chat.value;
chat.value = "";
websocket.send(message);
}
</script>
</section>
</body>
</head>
</html>
チャットアプリケーションの主な機能と出力については、以下で説明します-
テストするには、Web Socketをサポートする2つのウィンドウを開き、上記のメッセージを入力してReturnキーを押します。これにより、チャットアプリケーションの機能が有効になります。
接続が確立されていない場合は、以下のように出力できます。
成功したチャット通信の出力を以下に示します。
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接続を適切に処理できません。同時に多数の接続を開いたままにするには、低いパフォーマンスコストで高い同時実行性を受け取るアーキテクチャが必要です。
プロトコルはセキュリティ上の理由から設計する必要があります。WebSocketはまったく新しいプロトコルであり、すべてのWebブラウザーが正しく実装しているわけではありません。たとえば、仕様では逆のことを暗示していますが、HTTPとWSの組み合わせを許可しているものもあります。この章では、ユーザーが知っておくべきいくつかの一般的なセキュリティ攻撃について説明します。
サービス拒否
サービス拒否(DoS)攻撃は、マシンまたはネットワークリソースを、それを要求するユーザーが利用できないようにしようとします。誰かがWebサーバーに対して、時間間隔がないか、わずかな時間間隔で無限の数の要求を行ったとします。サーバーは各接続を処理できず、応答を停止するか、応答が遅すぎます。これは、サービス拒否攻撃と呼ぶことができます。
サービス拒否は、Webページをロードすることさえできなかったエンドユーザーにとって非常に苛立たしいものです。
DoS攻撃はピアツーピア通信にも適用される可能性があり、P2Pネットワークのクライアントが被害者のWebサーバーに同時に接続することを余儀なくされます。
真ん中の男
例を使ってこれを理解しましょう。
人を想定します A 彼の友人とチャットしています BIMクライアント経由。第三者があなたが交換したメッセージを見たいと思っています。それで、彼は両方の人と独立したつながりを作ります。彼はまた人にメッセージを送りますA と彼の友人 B、あなたのコミュニケーションの目に見えない中間体として。これは、man-in-the-middle攻撃として知られています。
中間者攻撃は、侵入者がパッケージを直接読み取ることができるため、暗号化されていない接続の方が簡単です。接続が暗号化されている場合、攻撃者は情報を復号化する必要がありますが、これは非常に難しい場合があります。
技術的な観点から、攻撃者は公開鍵メッセージ交換を傍受し、要求された鍵を自分のものに置き換えながらメッセージを送信します。明らかに、攻撃者の仕事を困難にするための確実な戦略は、WebSocketでSSHを使用することです。
ほとんどの場合、重要なデータを交換するときは、暗号化されていないWSではなくWSSの安全な接続を優先します。
XSS
クロスサイトスクリプティング(XSS)は、攻撃者がクライアント側のスクリプトをWebページまたはアプリケーションに挿入できるようにする脆弱性です。攻撃者は、アプリケーションハブを使用してHTMLまたはJavascriptコードを送信し、このコードをクライアントのマシンで実行させることができます。
WebSocketのネイティブ防御メカニズム
デフォルトでは、WebSocketプロトコルは安全になるように設計されています。現実の世界では、ブラウザの実装が不十分なために発生する可能性のあるさまざまな問題がユーザーに発生する可能性があります。時間が経つにつれて、ブラウザベンダーは問題をすぐに修正します。
SSH(またはTLS)を介した安全なWebSocket接続が使用されている場合、セキュリティの追加レイヤーが追加されます。
WebSocketの世界では、主な関心事は安全な接続のパフォーマンスです。上部にはまだ追加のTLSレイヤーがありますが、プロトコル自体にはこの種の使用のための最適化が含まれており、さらにWSSはプロキシを介してよりスムーズに機能します。
クライアントからサーバーへのマスキング
WebSocketサーバーとWebSocketクライアント間で送信されるすべてのメッセージには、マスキングキーという名前の特定のキーが含まれています。これにより、WebSocket準拠の仲介者はメッセージのマスクを解除して検査できます。仲介者がWebSocketに準拠していない場合、メッセージは影響を受けません。WebSocketプロトコルを実装するブラウザーは、マスキングを処理します。
セキュリティツールボックス
最後に、WebSocketクライアントとサーバー間の情報の流れを調査し、交換されたデータを分析し、考えられるリスクを特定するための便利なツールを紹介できます。
ブラウザ開発ツール
Chrome、Firefox、Operaは、開発者サポートの点で優れたブラウザです。彼らの組み込みツールは、クライアント側の相互作用とリソースのほぼすべての側面を決定するのに役立ちます。これは、セキュリティの目的で大きな役割を果たします。
WebSocketは、その名前が示すように、Webを使用するものです。Webは通常、ブラウザページと織り交ぜられています。これは、ブラウザページがデータをオンラインで表示するための主要な手段であるためです。ただし、ブラウザ以外のプログラムもオンラインデータ転送を使用します。
iPhone(当初)とiPad(後期)のリリースにより、必ずしもWebブラウザーを使用せずに、Web相互接続のまったく新しい世界が導入されました。代わりに、新しいスマートフォンとタブレットデバイスは、ネイティブアプリのパワーを利用して、独自のユーザーエクスペリエンスを提供しました。
なぜモバイルが重要なのですか?
現在、10億台のアクティブなスマートフォンがあります。つまり、アプリケーションの何百万もの潜在的な顧客です。これらの人々は、携帯電話を使用して、日常のタスクを実行したり、インターネットをサーフィンしたり、通信したり、買い物をしたりします。
スマートフォンはアプリの代名詞になっています。今日では、ユーザーが考えることができるあらゆる用途のためのアプリがあります。ほとんどのアプリは、データの取得、トランザクションの実行、ニュースの収集などのためにインターネットに接続します。
既存のWebSocketの知識を使用して、スマートフォンまたはタブレットデバイスでネイティブに実行されるWebSocketクライアントを開発することは素晴らしいことです。
ネイティブモバイルアプリとモバイルウェブサイト
まあ、これは一般的な対立であり、いつものように、答えはターゲットオーディエンスのニーズに依存します。ユーザーが最新のデザイントレンドに精通している場合は、応答性が高くモバイルフレンドリーなWebサイトをデザインする必要があります。ただし、エンドユーザーは、実際に重要なコンテンツが、従来のデスクトップブラウザと同じようにスマートフォンからもアクセスできることを確認する必要があります。
間違いなく、WebSocket Webアプリは、iOS用のSafariやモバイル用のChromeなどのモバイルブラウザーを含む、HTML5準拠のブラウザーで実行されます。そのため、スマートフォンとの互換性の問題はありません。
前提条件
スマートフォンアプリを開発するには、開発ツールとSDKのインストールが必要です。
WebSocketは、接続されたモバイルクライアントとタブレットクライアント間でメッセージを送信するためのユニバーサルハブとして機能できます。HTML5JavaScriptクライアントと同じようにWebSocketサーバーと通信するネイティブiOSアプリケーションを実装できます。