概要
SSE (Server-Sent Events) は、サーバーがリアルタイムでクライアントにデータをプッシュできるようにする HTTP ベースのサーバー プッシュ テクノロジです。従来のポーリングまたはロング ポーリング技術と比較して、SSE は遅延が短く、効率が高く、リソース消費が少なくなります。
SSE は HTML5 仕様で初めて導入され、インスタント メッセージング、株価、ニュース情報などのさまざまな Web アプリケーションで広く使用されています。SSE の動作原理は非常に単純で、クライアントはサーバーとの長い接続を確立し (つまり、HTTP 接続は閉じられません)、サーバーはいつでもクライアントにデータをプッシュでき、クライアントはリッスンしてデータを取得します。この接続上のイベントに送信します。
SSE の利点には主に次の側面が含まれます。
-
優れたリアルタイム パフォーマンス: SSE はリアルタイムでデータをプッシュでき、ポーリングやロング ポーリングよりも高速にデータをクライアントに送信できます。
-
リソースの節約: SSE は長い接続を確立するだけでよく、頻繁に接続を確立したり閉じたりする必要がなく、従来のポーリングまたはロング ポーリング テクノロジと比較して、サーバーとクライアントのリソースを節約できます。
-
高い信頼性: SSE は、互換性と安定性に優れた HTTP プロトコルを通信に使用し、ネットワーク異常時に自動的に再接続できる自動再接続メカニズムも備えています。
-
使いやすさ: SSE の実装は非常に簡単で、ブラウザーの組み込み EventSource オブジェクトを使用するだけで、リアルタイムのデータ プッシュを実現できます。
上記の利点に加えて、SSE には次の特徴もあります。
-
一方向通信: SSE はサーバーからクライアントにデータをプッシュすることしかできませんが、クライアントはサーバーにデータを送信できません。
-
テキスト データ: SSE はテキスト データの送信のみをサポートし、バイナリ データは送信できません。
-
ステートレス: SSE はステートレス プロトコルです。つまり、データがプッシュされるたびに完全な HTTP 応答ヘッダーを再送信する必要があります。
SSE を使用する場合は、次の点に注意する必要があります。
-
ブラウザの互換性: SSE は HTML5 仕様の一部となっていますが、すべてのブラウザが SSE をサポートしているわけではありません。SSE を使用する場合は、ブラウザーの互換性の問題に注意する必要があります。
-
サーバーの実装: SSE では、サーバーがデータをプッシュするロジックを実装する必要があり、実装中にスレッドの安全性や同時実行性などの問題を考慮する必要があります。
-
データ形式: SSE はテキスト データの送信のみをサポートしているため、データを送信するときにデータを文字列形式に変換する必要があります。
つまり、SSE は非常に実用的なサーバー プッシュ テクノロジであり、Web アプリケーションでの幅広い応用が期待されています。SSE を使用する場合は、セキュリティと安定性だけでなく、ブラウザの互換性、サーバーの実装、データ形式などの問題にも注意する必要があります。
SSE VS WS
SSE (Server-Sent Events) と WebSocket はどちらも、サーバーがクライアントにデータをプッシュできるようにするテクノロジーですが、実装、アプリケーション シナリオ、パフォーマンスが異なります。
1. 実施方法
SSE は HTTP プロトコルに基づくテクノロジーであり、HTTP 接続を使用してデータをクライアントにプッシュします。クライアントが HTTP 接続を開くと、サーバーは接続を通じてクライアントに継続的にデータを送信できます。SSE は一方向通信を使用します。つまり、サーバーのみがクライアントにデータを送信でき、クライアントはサーバーにデータを送信できません。
WebSocket は全二重通信プロトコルであり、接続が確立されると、クライアントとサーバーは相互にデータを送信できます。WebSocket は、HTTP プロトコルとは異なる独立したプロトコルである TCP 接続を使用します。
2. 応用シナリオ
SSE は、株価やチャット ルームなど、リアルタイムのデータ プッシュが必要なシナリオに適しています。SSE は HTTP プロトコルを使用するため、HTTP のキャッシュ メカニズムを使用してパフォーマンスを向上させることができます。さらに、SSE は、接続の安定性を確保するために再試行フィールドを設定することにより、自動的に再接続することもできます。
WebSocket は、オンライン ゲームやビデオ会議など、双方向通信が必要なシナリオに適しています。WebSocketはTCP接続を使用するため、データ通信の安定性と信頼性が保証されます。
さらに、WebSocket はバイナリ データ送信もサポートしており、オーディオやビデオなどの大きなファイルの送信に使用できます。
3. パフォーマンス
SSE と WebSocket にはパフォーマンスの点でも違いがあります。SSE は HTTP プロトコルを使用するため、データが送信されるたびに HTTP 接続を再確立する必要があり、追加のオーバーヘッドが発生します。また、SSE はサーバーからクライアントへのデータ送信のみが可能なため、双方向通信はできません。
WebSocket ではこうした問題はなく、TCP 接続を使用するため、長時間の接続を維持でき、毎回接続を確立するオーバーヘッドを回避できます。さらに、WebSocket は双方向通信をサポートしているため、クライアントとサーバー間のリアルタイムの対話が可能です。
4. まとめ
SSE と WebSocket はどちらも、サーバーがクライアントにデータをプッシュできるようにするテクノロジーですが、実装、アプリケーション シナリオ、パフォーマンスが異なります。
SSE はリアルタイムでデータをプッシュする必要があるシナリオに適しており、WebSocket は双方向通信が必要なシナリオに適しています。
パフォーマンスの点では、WebSocket の方が優れており、長時間の接続とリアルタイムの対話を維持できます。したがって、テクノロジーを選択するときは、特定のニーズに応じて選択する必要があります。
コード
最新の Web アプリケーションでは、リアルタイム データの必要性がますます一般的になってきています。従来のAjaxポーリングやロングポーリング技術はリアルタイムのデータ更新を実現できますが、いずれもサーバー負荷や遅延が大きいなどのデメリットがありました。SSE (Server-Sent Events) テクノロジーは、より効率的なリアルタイムのデータ更新方法です。
SSE は、HTTP プロトコルに基づくサーバー プッシュ テクノロジです。これにより、クライアントがリクエストを開始する必要がなく、サーバーがクライアントにデータをプッシュできるようになります。SSE は長い接続を使用するため、サーバーはいつでもクライアントにデータを送信して、リアルタイムの更新を実現できます。
SSE プロトコルは、「text/event-stream」と呼ばれる特別な HTTP 応答形式を定義します。この特別な HTTP 応答をサブスクライブすることにより、クライアントはサーバーによってプッシュされたデータを受信できます。SSE は、プッシュ データをより適切に整理および解析するためのイベント タイプや注釈などの機能もサポートしています。
Spring Boot での SSE の使用
Spring Boot で SSE を使用するのは非常に簡単です。まず、依存関係を追加する必要があります。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
私たちは webflux を使用しています。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
次に、コントローラーに @RequestMapping アノテーションを追加し、products 属性を「text/event-stream」として指定します。
@RestController
public class SSEController {
@RequestMapping(value = "/sse", produces = "text/event-stream")
public ResponseEntity<Flux<String>> sse() {
Flux<String> flux = Flux.interval(Duration.ofSeconds(1)).map(i -> "message " + i);
return ResponseEntity.ok().body(flux);
}
}
上記のコードは、Flux オブジェクトを返す「/sse」というルートを定義しています。Flux は、各要素間に指定された時間間隔で無制限の数の要素を生成できるリアクティブ ストリームです。上の例では、1 秒ごとにメッセージを送信します。
最後に、サーバーによってプッシュされたデータを受信するには、クライアント側でこのルートをサブスクライブする必要があります。JavaScript では、EventSource オブジェクトを使用して SSE にサブスクライブできます。
var eventSource = new EventSource('/sse');
eventSource.onmessage = function(event) {
console.log('Received message: ' + event.data);
};
上記のコードは EventSource オブジェクトを作成し、「/sse」ルートにサブスクライブします。サーバーがメッセージをプッシュすると、onmessage コールバック関数がトリガーされ、受信したメッセージが出力されます。
インデックスのコード全体は次のとおりです
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SSE-DEMO</title>
</head>
<body>
<h1>SSE - Flux</h1>
<div id="sse-flux"></div>
<script>
const eventSource = new EventSource('/sse');
eventSource.onmessage = function (event) {
document.getElementById("sse-flux").innerHTML = event.data;
console.log('Received message: ' + event.data);
};
</script>
</body>
</html>
テスト
要約する
Spring Boot で SSE テクノロジーを使用してリアルタイムのデータ更新を実現する方法を紹介しました。SSE は非常に効率的で使いやすいサーバー プッシュ テクノロジであり、Web アプリケーションのリアルタイム パフォーマンスを大幅に向上させることができます。SSE を使用する場合、ルートを定義して Flux オブジェクトを返す必要があります。クライアントは、EventSource オブジェクトを通じてこのルートをサブスクライブし、サーバーによってプッシュされたデータを受信できます。
リアルタイムのデータ更新を必要とする Web アプリケーションを開発している場合は、それを実現するために SSE テクノロジーの使用を検討することをお勧めします。アプリケーションをより効率的、高速かつ信頼性の高いものにすることができます。