5分でわかるHTML5 WebSocketプロトコル
1. 背景
プッシュ技術を実装するために多くのウェブサイトで使われている技術にAjaxポーリングがあります。ポーリングとは、一定時間ごとにブラウザからサーバにHTTPリクエストを行い、サーバからクライアントブラウザに最新データを返すというものです。この従来のモデルは、ブラウザがサーバーにリクエストを送り続ける必要があるという明らかな欠点があるが、HTTPリクエストには長いヘッダーが含まれることがあり、そのうち実際に有効なデータはごく一部なので、明らかに多くの帯域やその他のリソースを浪費している。そのため、サーバーのリソースや帯域を節約し、リアルタイムな通信を可能にします。
2. WebSocketの紹介
従来のhttpもプロトコルであるが、WebSocketはhttpサーバーでは実装できないプロトコルである。
2.1. ブラウザ対応
主要なブラウザでサポートされています
2.2. メリット
httpでは、以下のようなメリットがあります。
1. クライアントはサーバーとの間に1つのTCP接続を確立するだけなので、使用する接続数を少なくすることができます。
2. WebSocket サーバー側が能動的にデータをクライアントにプッシュできるため、より柔軟で効率的な運用が可能です。
3. プロトコルヘッダを軽量化し、転送データ量を削減。
ロータルトレーニング機構との対比
3. WebSocketの使用方法
WebSocketが何であり、何を提供するかを理解した上で、どのように使用するか?
3.1. WebSocketの作成
WebSocket は、http とは少し異なる url パターンのカスタム プロトコルを使用します。暗号化されていない接続は ws://、暗号化された接続は wss:// となり、WebSocket インスタンスでは、このパターンを使用します。
new WebSocket()
メソッドで作成します。
var ws = new WebSocket(url, [protocol] );
最初のパラメータであるurlは、接続のURLを指定します。2番目のパラメータであるprotocolは、オプションで、許容されるサブプロトコルを指定します。
3.2. WebSocketのプロパティ
ws オブジェクトが生成されると、readyState が ws インスタンスの状態となり、次の 4 つの状態があります。
0 は接続が確立されていないことを意味します。
1 接続が確立され、通信可能な状態であることを示す。
2 接続が切断処理中であることを示す。
3 接続が終了しているか、接続を開くことができないことを示す。
ヒント メッセージを送信する前にステータスを判断し、切断された場合の再接続メカニズムが必要です。
3.3. WebSocketイベント
wsインスタンスオブジェクトを生成すると、以下のようなイベントが発生し、その状態に応じて、イベントコールバックにメソッドを記述することができるようになります。
- ws.onopen 接続確立時に発生
- ws.onmessage クライアントがサーバーからデータを受信したときに起動される
- ws.onerror 通信エラーが発生したときに発生する。
- ws.onclose 接続が閉じられたときに発生する
ws.onmessage = (res) => {
console.log(res.data);
};
ws.onopen = () => {
console.log('OPEN...') ;
};
ws.onclose = () => {
console.log('CLOSE...') ;
}
3.4. WebSocketのメソッド
- ws.send() 接続を使用してデータを送信します (プレーンテキストデータのみ送信可能)
- ws.close() は、接続を閉じます。
4、デモデモ
WebSocketのAPIをある程度理解したら、鉄が熱いうちに小さなケースを実行させる。
4.1. Nodeサーバーサイド
WebSocketプロトコルは、2つの理由からNodeと非常にうまく動作します。
1. WebSocketクライアントサイドイベントベースのプログラミングは、Nodeのカスタムイベントとほとんど同じです。
2. WebSocketは長いクライアント・サーバ接続を実装しており、Nodeの基本的なイベント駆動型アプローチは高い並行性接続に適している
以下のように、webSocket.jsを作成します。
const WebSocketServer = require('ws').Server;
const wss = new WebSocketServer({ port: 8080 });
wss.on('connection', function (ws) {
console.log('client connected');
ws.on('message', function (message) {
ws.send('I received' + message);
});
});
Windowsのコマンドウィンドウを開き、以下を実行します。
4.2. HTMLクライアント
新しいindex.htmlページを作成する
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>webSocketSmallDemo</title>
</head>
<body>
<div class="container">
<div>
<input type="text" id="msg">
<button onclick="sendMsg()">Send message</button>
</div>
</div>
<script>
const ws = new WebSocket('ws://localhost:8080');
ws.onmessage = (res) => {
console.log(res);
};
ws.onopen = () => {
console.log('OPEN...') ;
};
ws.onclose = () => {
console.log('CLOSE...') ;
}
function sendMsg() {
let msg = document.getElementById('msg').value;
ws.send(msg);
}
</script>
</body>
ブラウザを開き、1,2,3の文字を順番に入力し、メッセージ本文の送信をクリックするたびに、送信したメッセージがws.onmessageイベントのres.dataに返されます。
5. 質問とまとめ
以上、WebSocket APIの概要と簡単な使い方を紹介しました。チャットルームのような高い同時実行性と長い接続を扱う場合は、WebSocket http リクエストの方がより適切で効率的であると思われます。
しかし、WebSocketを使う過程で、切断しやすいなどの問題があることがわかり、各メッセージを送る前に切断するかどうかを判断する必要があったり、複数のメッセージを送る場合、サーバーから返ってくるデータの量が異なるため、クライアントに返す前後の順番が異なり、前のメッセージで返ってきたデータをクライアントが受け取った後に次のメッセージを送る必要があったり、コールバックが過剰にネストしないよう Promise, async, awaitなどの同期をとる方法で解決できることがわかったりしました。WebSocketはここまで、不備があればもっと訂正を歓迎します
今回書いたのはここまでです。勉強になれば幸いです。そして、Scripting Houseを応援していただければ幸いです。
関連
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
キャンバスを使って動画の一瞬をスクリーンショットで撮影する
-
html5対応ブラウザの確認方法
-
Html5ネイティブのドラッグ&ドロップ関連イベント紹介と基本的な実装方法
-
キャンバス描画の解像度が拡大され、ぼやけた状態になる
-
videoタグによるストリーミング読み込みのhtml5実装
-
htmlでspanの幅を設定する方法
-
プリントイメージ機能のフロントエンド実装
-
キャンバスを使用して、実装の画像にタイル状の透かしを追加することを教える手
-
html2canvas.jsを使用してページのスクリーンショットを撮影し、表示またはアップロードするサンプルコード
-
HTML5ページシームレス点滅オープン問題と解決策