Chapter 39

techniques-serversentevents

kisihara.c
kisihara.c
2021.07.04に更新

サーバーセントイベント

Server-Sent Events(SSE)はサーバープッシュ技術の一つで、HTTP接続を介した、サーバーによるクライアント自動更新を可能とする。各通知は改行で終わるテキストのブロックとして送信される(詳細)。

使用

ルート(コントローラクラスに登録されたルート)でServer-sentイベントを起こすには、@Sseデコレータでメソッドハンドラをアノテートする。

@Sse('sse')
sse(): Observable<MessageEvent> {
  return interval(1000).pipe(map((_) => ({ data: { hello: 'world' } })));
}

HINT
@Sse()デコレータは@nestjs/commonから、Observableintervaland maprxjsパッケージからインポートされている。

WARNING
サーバーセントイベントはObservableストリームを返す必要がある。

上の例では、sseという名前のルートを定義して、リアルタイムの更新を伝播できるようにしている。これらのイベントはEventSource APIを使ってリッスンする。

sseメソッドは、複数のMessageEventを発行するObservableを返す(この例では1秒ごとに新しいMessageEventを発行)。MessageEventオブジェクトは、仕様に合わせて以下のインターフェイスを尊重(respect)する必要がある。

export interface MessageEvent {
  data: string | object;
  id?: string;
  type?: string;
  retry?: number;
}

これで、クライアントサイドにアプリケーションでEventSourceクラスのインスタンスを作成し、コンストラクタの引数に/sseルート(上記の@Sseデコレータに渡したエンドポイントと一致)を渡すことができる。

EventSourceのインスタンスは、HTTPサーバーへの持続的な接続を開き、イベントをtext/event-stream形式で送信する。この接続はEventSource.close()をコールして閉じるまで開いたままとなる。

接続が開かれると、サーバからの受信メッセージがイベントの形でコードに配信される。受信メッセージにイベント・フィールドがある場合トリガーされるイベントはイベントフィールドの値と同じものだ。イベントフィールドが存在しない場合は、一般的なmessageイベントが発生する(情報元)。

const eventSource = new EventSource('/sse');
eventSource.onmessage = ({ data }) => {
  console.log('New message', JSON.parse(data));
};

サンプル

動くサンプルはこちら