第一章:HTTP vs WebSocket の違い:なぜチャットアプリには双方向リアルタイム接続が必要なのか?
従来のウェブアプリケーション開発では、ほとんどHTTPプロトコルを使用しています。しかし、「リアルタイムインタラクティブ(Real-time)」アプリ(LINEのチャットルーム、株価表示ソフト、またはChatGPTのように文字が次々と表示されるAIなど)を開発する場合、従来のHTTPでは非常に非効率になります。
この章では、ネットワークプロトコルの基礎から解説し、なぜ高度な商業プロジェクトを開発する際にHTTPの快適圏を超えてWebSocketやStreaming(SSEストリーミング)技術を採用する必要があるのかを理解していただきます。これは「初級ウェブデザイナー」から「フルスタックアーキテクト」へ成長するための必須の道程です。
🛑 従来のHTTPの制限:一方向かつ短命
HTTP(HyperText Transfer Protocol)のコアモデルは 「Request-Response(リクエストとレスポンス)」 モデルです。 これをタピオカミルクティーを買う行為に例えると:
- Request(リクエスト発行):あなた(フロントエンド)がカウンターに行き「タピオカミルクティーをください」と注文します。
- Processing(処理中):店員がお茶を淹れます(バックエンドサーバーが計算やデータベース検索を実行中)。
- Response(レスポンス):店員がタピオカミルクティーを渡します。
取引が終わると、あなたと店員の間の「接続」は完全に切れます。これは 「Stateless(ステートレス)」 と呼ばれます。 「新しいストロベリー味はありますか?」と知りたい場合、その場で店員からの返事を待つことはできず、「再度カウンターに行って質問する」必要があります。
致命的なパフォーマンスキラー:Polling(ポーリング)
従来のHTTPで多人チャットルームを実装しようとすると何が起こるでしょうか? サーバーは「能動的」にウェブページに連絡できないため、ウェブページはタイマーを設定し、1秒ごとにサーバーに問い合わせる必要があります:
```javascript // 俗に言うShort Polling(ポーリング) - 初心者が陥りやすいパフォーマンス災害 setInterval(async () => { const response = await fetch('/api/get-new-messages?lastMsgId=999') const newMessages = await response.json()
if (newMessages.length > 0) { renderMessages(newMessages) } }, 1000) // 1秒ごとに無条件でサーバーにリクエスト ```
これによってどんな壊滅的な結果が生じるか?
- 無効なリクエストが多すぎる:10分間誰も発言しなかった場合でも、ウェブページは600回の`fetch`リクエストを発行します。
- サーバーの瞬間的なクラッシュ:10,000人のオンラインユーザーがいる場合、サーバーは「毎秒」10,000件の「新しいメッセージはありますか?」という無駄なリクエストを処理しなければなりません。サーバーのCPUとデータベース接続プールは瞬時に枯渇し、ダウンします(さらにAWSやVercelのクラウド請求書が天井知らずになります)。
⚡ WebSocketの誕生:専用の双方向ホットライン
ポーリングによるパフォーマンス災害を解決するため、HTML5時代に WebSocket プロトコルが誕生しました。
WebSocketは、サーバーと「専用のホットライン」を確立し、双方が切断しない状態を維持します。 これはHTTPの「クライアントからのリクエストのみ可能」という鉄則を打ち破ります!
WebSocketの動作3ステップ:
- Handshake(ハンドシェイク段階):ウェブページがサーバーに特殊なタグ`Upgrade: websocket`を含むHTTPリクエストを送信し、「WebSocketで通信しませんか?」と提案します。
- Bi-directional(双方向通信):サーバーが承諾すると、接続が確立されます。これにより、ウェブページはいつでもサーバーにメッセージを送信できるだけでなく、サーバーもいつでも能動的にメッセージをプッシュ(Push)できます!
- 超低遅延:HTTPのように毎回パケットに重いヘッダー(Cookie、User-Agentなど)を詰め込む必要がなく、WebSocketのデータフレーム(Data Frame)は非常に軽量で、メッセージ伝達が電光石火の速さで行われます。
チャットルームシナリオの魔法
チャットアプリのシナリオでは、ユーザーAが「こんにちは」とサーバー��送信すると、サーバーはユーザーBからの問い合わせを待たずに、確立済みのWebSocket回線を通じて「こんにちは」をBの画面にブロードキャスト(Broadcast)できます。 これが、LINEを使用している際に相手が送信ボタンを押すと「瞬時に」通知が表示され、遅延が全くない理由です。
🌊 現代AIの基盤:Server-Sent Events(SSE)とStreaming
WebSocket以外に、AI(特にLLM大規模言語モデル)の爆発的普及により、 Streaming(ストリーミング) と SSE(Server-Sent Events) という技術も非常に注目されています。
ChatGPTを使用する際、回答が「一文字ずつ」ゆっくり表示されることに気付くでしょう。これが有名なタイプライター効果です。 なぜAIは従来のHTTPのように、記事全体が完成してから「一気に」返信できないのでしょうか?
AI演算の物理的限界
大規模言語モデル(LLM)の演算速度には限界があります。GPT-4のような巨大モデルでは、1000文字の記事を生成するのに15秒から30秒かかる場合があります。 従来のHTTPを使用すると、ユーザーはリクエストを送信した後、くるくる回るLoadingアイコンを見つめ、15秒間白紙を眺めることになります。現代のウェブユーザー体験(UX)では、3秒以上画面が更新されないと「サイトが壊れた」と思われ、ページを閉じられてしまいます。
そのため、AI業界では Streaming 技術が全面的に採用されています。 サーバーは最初の文字が計算でき次第、即座にその文字を閉じていない接続に「詰め込んで」フロントエンドに送信します。2文字目が計算できたら、2文字目を送信します。フロントエンドは文字を受け取るたびに即座に画面に表示し、ユーザーに「AIが猛烈にタイプしている」という超高速の錯覚を与えます。
SSE(Server-Sent Events)の基本原理
SSEはWebSocketと似ていますが、従来のHTTPプロトコルを使用し、**「単方向」**の長い接続です。
- ウェブページがサーバーにHTTP GET/POSTリクエストを送信します。
- サーバーはHeader `Content-Type: text/event-stream`を返し、ブラウザに「このデータはまだ送信途中です。この接続を閉じずに、新しい断片(Chunk)をどんどん送ります」と伝えます。
- その後、サーバーは新しいテキストをこの接続に継続的にプッシュできます。
この技術はAI対話のシナリオに完璧に適合します。ユーザーが質問を送信した後、AIからの返答を「受動的に受け取る」だけでよく、WebSocketのような双方向チャネルを確立する必要がないため、サーバーの接続維持負担が大幅に軽減されます。
🛠️ 現代リアルタイムアプリの技術選択(このコースの青図)
まとめると、2024年に商業級SaaSを開発する際は、異なるシナリオに応じて適切なリアル���イム通信技術を選択する必要があります:
-
Supabase Realtime(基盤はWebSocket):
- シナリオ:データベースの変更を監視する場合。例:「チャットルームの多人リアルタイムメッセージ」、「共同ドキュメント編集」、「リアルタイム株価表示」。
- 利点:双方向通信、超低遅延。
-
AI Streaming API(SSEの現代版):
- シナリオ:OpenAI / Anthropicサーバーに接続し、AI生成文章を受信する場合。
- 利点:軽量、HTTPをネイティブサポート、Vercel AI SDKのタイプライター効果に完璧対応。
準備はいいですか?理論編はここまでです。 次の章では、実戦に直接入り、Supabase Realtimeから始め、「ポーリングコードを一切書かずに、データベースが変更されるとフロントエンド画面に自動プッシュされる」超魔法を目の当たりにします!