SSE(Server-Sent Events)の理解とその利点

February 1, 2024

Technology

はじめに

SSE (Server-Sent Events) は、HTTPプロトコルに基づいたクライアントとサーバー間の単方向通信プロトコルです。これにより、サーバーはクライアントからの明示的なリクエストを必要とせずに、イベントストリームを使用してリアルタイムでデータをクライアントにプッシュできます。標準のHTTPプロトコルに基づいて構築されたSSEは、単方向の永続的な接続を利用し、サーバーがクライアントにイベントやデータを積極的に送信できるようにします。

Server-Sent Events

基本的には、ストリーミング方式で実装されており、クライアントがサーバーに接続リクエストを開始し、接続を開いたままにします。サーバーはその後、クライアントにメッセージを積極的にプッシュします。Server-Sent Events (SSE) を使用してサーバーからクライアントに送信されるデータは、UTF-8エンコードされている必要があり、返されるコンテンツタイプは text/event-stream です。例えば、ChatGPTを使用する際に質問をすると、答えが単語ごとに表示されるのを見ることができます。実際には、ChatGPTは事前に計算されたデータを積極的に「プッシュ」しており、SSE技術を使用して計算しながらデータを返すことで、長いインターフェース待ち時間によるページの直接閉鎖を防いでいます。

Example of server-sent events

SSEの利点

  1. リアルタイム通信: SSEはリアルタイム通信メカニズムを提供し、サーバーがクライアントにデータを積極的にプッシュできるようにします。このリアルタイム機能により、SSEはリアルタイムチャット、オンラインコラボレーションツール、リアルタイムデータ表示、通知配信など、即時の更新を必要とするアプリケーションに特に適しています。

  2. ネットワーク負荷の軽減: 従来のポーリング方式と比較して、SSEは長寿命の接続を利用します。単一のHTTP接続を通じて、サーバーはクライアントに複数のイベントをプッシュでき、頻繁なHTTPリクエストを回避し、ネットワーク負荷を軽減します。

  3. 軽量: SSEはHTTPプロトコルに基づいており、既存のサーバーソフトウェアでサポートされており、WebSocketと比較して使用が簡単です。

  4. 自動再接続: SSEは接続が中断された後、自動的に再接続を試みることができ、追加のコードを必要としません。この自動再接続メカニズムにより、システムの安定性が向上し、不安定なネットワーク条件下でも継続的な通信が保証されます。

API7 Enterpriseを使用したSSEサービスのプロキシ

実際のアプリケーションでは、APIゲートウェイを活用してSSEサービスをプロキシすることは、サービスの安定性を向上させ、セキュリティやクロスオリジンの問題を解決し、複雑なアプリケーションシナリオを処理するのに適しています。NGINXは最も人気のあるリバースプロキシサーバーの1つであり、かなりの市場シェアを持っています。

NGINXでSSEサービスをプロキシする場合、proxy_buffering を無効にする必要があります。ただし、この設定は少なくともロケーションレベルで閉じる必要があり、システム内に複数のロケーションがあり、SSEサービスをサポートするためにキャッシュを無効にする必要がある場合、他の非SSE APIのパフォーマンスに影響を与える可能性があります。さらに、NGINXの proxy_buffering 設定は柔軟性に欠けており、実行時に動的に有効または無効にすることができず、設定の再読み込みが必要であり、サービス中断を引き起こす可能性があります。

API7 Enterpriseproxy-buffering プラグインを提供しており、SSEアップストリームサービスをより柔軟にプロキシできます。対応するルートでこのプラグインを有効にすることで、設定全体を再読み込みすることなく、キャッシュを簡単に制御できます。この柔軟性により、SSEサービスのプロキシ要件を満たすと同時に、パフォーマンスと動的設定のニーズにも対応できます。

SSE plugin of API7 Enterprise

以下のテストにより、SSEサービスのプロキシが成功したことが確認されます。

curl "http://127.0.0.1:9080/.sse" -H "Accept: text/event-stream"

event: server
data: 27d365b177ae
id: 1

event: request
data: GET /.sse HTTP/1.1
data:
data: Host: 127.0.0.1:9080
data: Accept: text/event-stream
data: User-Agent: curl/8.1.2
data: X-Forwarded-For: 192.168.65.1
data: X-Forwarded-Host: 127.0.0.1
data: X-Forwarded-Port: 9080
data: X-Forwarded-Proto: http
data: X-Real-Ip: 192.168.65.1
data:
id: 2

event: time
data: 2024-01-29T04:04:20Z
id: 3

event: time
data: 2024-01-29T04:04:21Z
id: 4
...

結論

まとめると、SSEはリアルタイム通信と更新を必要とするシナリオに適しており、これを実現するためのシンプルで効果的な手段を提供します。ただし、SSEは単方向チャネルであり、サーバーがクライアントにメッセージを送信することしかできないことに注意が必要です。そのため、SSEはすべてのタイプのリアルタイム通信ニーズに適しているわけではありません。より複雑な双方向通信シナリオでは、WebSocketや他の技術がより適している場合があります。

Tags: