通信

Server-Sent Events(SSE):サーバからクライアントに対しリアルタイムでイベントを送信できる技術。サーバとのコネクションを張っておいて、サーバからイベントを好きなタイミングで送れるイメージ。

WebSocketとは異なって単方向の通信であり、またHTTP上で動作するので実装も容易。

ChatGPTでもSSEが使われていて、1トークン生成ごとにサーバから生成した文字列を含んだイベントを送信することで文章がどんどん表示される。
ここでいうトークンとは、「単語の断片」のこと。ChatGPTのAPIの料金はこのトークン数に応じて課金される。

通常のHTTP通信ではクライアントがサーバにリクエストを送信し、サーバがそれに対しレスポンスを返す形式で通信が行われる。ただこれではサーバ側で何か変化があったとしても、リクエストを投げない限りクライアント側は新しいデータを受け取れない。なのでリアルタイムな情報の更新や通知が必要なチャットアプリやニュースフィード、株価アプリなどではリアルタイム通信の技術が活用される。

SSEの欠点として下記が挙げられる。
- 転送できるデータ形式が限定的であること
- 同時接続数が制限されているため拡張性に乏しいこと
- サーバ→クライアントの単方向の通信であるため、株価チェックなど読み取り専用のアプリ作成には便利だが、下記のようなアプリは双方向通信が必要
- 新しいメッセージの受信や既読状態の更新が必要なチャットアプリ(LINEとか)
- 変更の同期やコラボレーションを必要とする共同編集ツール(Notionとか)
- プレイヤーの行動や状態のリアルタイムな同期が必要なオンラインゲーム
- ユーザの位置情報をリアルタイムで共有する必要がある配送追跡・位置情報共有アプリ

ポーリング:クライアントが定期的にサーバにリクエストを送信して、データを取得する方法。

ロングポーリング:通常のポーリングとは異なり、サーバが新しいデータを用意するまでレスポンスを返さず、接続も閉じない。新しいデータが用意されたらサーバはそのデータでレスポンスを返し接続を閉じる。その後直ちにクライアントは新たなリクエストを送る

メリット
- 新しいデータが用意されるまで待機するので通常のポーリングよりもリアルタイム性を高められる
- 過剰なリクエストとレスポンスが発生しないので通信効率が向上する

デメリット
- クライアントが接続を維持することによるサーバのリソース消費
- 多数同時接続によるサーバのスケーラビリティへの影響
- 新たなデータが用意されるまでクライアントが待機することに

WebSocket:Webにおいて双方向通信を低コストで行うための仕組み。クライアントとサーバーが常にコネクションを維持することで双方向通信を実現している。この仕組みによって、サーバにリクエストを投げたりポーリングすることなくイベント駆動型のレスポンスを受信できる

通信が持続的に行われるのでポーリングやロングポーリングよりも高効率・高速なリアルタイム通信を実現できる。ゆえにチャットアプリやオンラインゲーム、コラボレーションツール、リアルタイムストリーミングアプリなどリアルタイム性が重要なアプリで利用される。

WebSocketはHTTPのハンドシェイクを経てTCP接続を確立し、その後はデータをフレーム単位で双方向に受信することで効率的なリアルタイム通信を実現する
- ハンドシェイク:通信を確立する際に行われる最初のプロトコルの交換。この交換により、通信を行うデバイスやシステムが互いに識別し、通信のパラメータやセキュリティ設定を合意できる
- フレーム:データの転送単位。

欠点
- 通信の初期設定やハンドシェイク、データのフレーム化などプロトコルの詳細を理解する学習コスト
- 一部のネットワーク環境における、プロキシやファイアウォールによるWebSocket通信の制約
- 古いブラウザでサポートされていない
- 接続維持によるサーバやクライアントのリソース消費
- セキュリティ面の懸念