【 HTTPプロトコル 】WebSocket/Socket.ioとは

# WebSocketとは

WebSocketとは、双方向通信を可能にする通信プロトコルです。通常のHTTP通信がクライアントからサーバーへのリクエストと、サーバーからクライアントへのレスポンスの単方向通信であるのに対し、WebSocketはクライアントとサーバー間でデータを双方向にやり取りできます。

主にウェブアプリケーションにおいて、リアルタイム機能やチャット、ライブ更新などの実装に使用します。WebSocketは通常、クライアントとサーバー間で特定のエンドポイント(URL)を通じて確立されます。

## 特徴

### 双方向通信
WebStockは双方向通信を提供しています。そのため、クライアントとサーバーがお互いにデータを送信できます。

### 低レイテンシ
通常のHTTP通信では、新しいデータを取得するためには定期的ポーリングする必要がありました。しかし、WebSocketは接続を維持し、サーバーからのデータがあれば即座に受信できるため、低レイテンシでリアルタイムな通信が可能です。

### セキュリティ
WebSocketはセキュアではない通信`ws://`と、セキュアな通信`wss://`の両方をサポートしています。セキュアな通信はTLS/SSLによって暗号化され、データの安全性を確保します。

### サブプロトコル
WebSocketは異なるアプリケーション間で異なる通信の形式を可能にするために、サブプロトコルの概念を取り入れています。サブプロトコルはクライアントとサーバーが通信できるようにするカスタムの通信プロトコルやフォーマットを指定するのに使用されます。

### WebSocket API
ウェヴヴらウザ上でWecSocketを利用するためには、JavaScriptからWebSocket APIを使用します。これにより。ウェブアプリケーションがクライアントサイドでWebSocket接続を確立し、データを送受信できます。

### プロキシサポート
WebSocketは通常、プロキシサーバーを通過します。ただし、一部のプロキシはWebSocket通信を遮断することがあり、この場合は設定を変更する必要があります。

### 自動再接続
WebSocketクライアントは、通信が途切れた場合に自動的に再接続を試みる機能を提供しています。これにより、一時的なネットワークの問題があっても通信が継続できるようになります。

※定期ポーリングとは
クライアントが一定の時間間隔でサーバーにリクエストを送り、新しい情報があるかどうかを確認する手法です。

### 効率的なデータ転送
WebSocketは軽量で効率的なプロトコルです。通信のオーバーヘッドが少ないため、リアルタイムな通信に適しています。

### 単一の接続
WebSocketは一度の接続で複数のメッセージをやり取りできます。

## 欠点
・１つのコネクションで１つのリクエストしか送信できない。
・リクエストはクライアントからしか送ることができない。
・サーバーから通信を始めることができない。
・ヘッダーが冗長。

## 通信料削減

以下の要素のおかげで、WebSocketプロトコルは通信料削減に寄与する協力なツールとなっています。

### 持続的なコネクション
WebSocketは一次コネクションが確立されると、その後の通信のためにコネクションを維持します。これにより、通信のたびに新しいコネクションを確立する必要がなく、その分のオーバーヘッドが削減されます。

### ヘッダの最適化
WebSocketのヘッダサイズはHTTPよりも小さいため、通信のオーバーヘッドが少なくなります。

### データのフラグメンテーションの削減
WebSocketはメッセージ単位でデータを送信するため、不必要なフラグメンテーションが発生しにくいです。これにより、通信効率が向上し、通信料を削減できます。

### サーバプッシュの最適利用
サーバプッシュ機能により、サーバーはクライアントに必要なデータをプッシュできます。これにより、クライアントがデータをリクエストする前に、必要な情報を受信できるため、通信の効率が向上し、通信料を削減できます。

## ハンドシェイク
ハンドシェイクとは、WebSocketプロトコルにおいてクライアントとサーバーが通信を開始する前に行われる最初のプロトコルのやり取りです。WebSocketは、HTTPプロトコルを使用して通信を確立するため、最初にHTTPを使用してハンドシェイクを行います。

## ハンドシェイクの基本的な手順

### 1.クライアントがサーバーに対してWebSocket接続をリクエストする。
クライアントはHTTPリクエストを使用して、WebSocket接続を要求します。
```http
GET /path/to/websocket/resource HTTP/1.1
Host: example.com
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Key: <base64-encoded-key>
Sec-WebSocket-Version: 13
```

### 2.サーバーがクライアントのリクエストに応じてハンドシェイクを受け入れる
サーバーはクライアントのリクエストを受け取り、応答を返します。これには、HTTPステータスコード101(Switching Protocols)が含まれます。
```http
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: <base64-encoded-accept-key>
```

### 3.通信がWebSocketに切り替わる
ハンドシェイクが成功すると、通信はWebSocketプロトコルに切り替わり、クライアントとサーバーは双方向でデータを送受信できるようになります。

# Socket.ioとは
Socket.ioは、クライアントとサーバー間でリアルタイムかつ双方向の通信を実現するJavaScriptライブラリです。チャットアプリケーション、オンラインゲーム、協力編集ツールなどに使われ、即座のデータ交換を実現します。

## 特徴

### リアルタイム通信
Socket.ioは、データの即時な双方向通信を可能にし、接続されたクライアントへのデータ更新を瞬時に伝達します。

### WebSocketのサポート
Socket.ioは、低遅延通信のためにWebSocketを使用します。WebSocketがサポートされていない場合でも、ロングポーリングなどの他の転送メカニズムにフォールバックが行われます。

### イベント駆動モデル
イベント駆動のモデルを採用しており、クライアントとサーバーはカスタムイベントを発行し、リッスンすることができます。そのため、アプリケーション内で特定のアクションを定義し、処理することが容易になります。

### クロスブラウザ対応
Socket.ioはクロスブラウザ対応を提供し、幅広いクライアントやアプリケーションに適しています。

※クロスブラウザとは
複数の異なるウェブブラウザ―で、ウェブページやウェブアプリケーションが同じように対応していること。

### ルームとネームスペース
グループ化されたクライアントや通信チャンネルを整理するためにルールとネームスペースの概念があります。



# 参考・引用

https://qiita.com/chihiro/items/9d280704c6eff8603389