金曜日, 7月 4, 2025
金曜日, 7月 4, 2025
- Advertisment -
ホームニューステックニュース生成AIチャットアプリで使うServer-Sent Events (SSE)の実装方法まとめ #フロントエンド - Qiita

生成AIチャットアプリで使うServer-Sent Events (SSE)の実装方法まとめ #フロントエンド – Qiita



生成AIチャットアプリで使うServer-Sent Events (SSE)の実装方法まとめ #フロントエンド - Qiita

はじめまして、花王株式会社の @TsuchiyaK です。

生成AIチャットアプリなどで「AIの回答をリアルタイムに順次表示したい」という要件はよくあるかと思います。
その際によく使われるのが Server-Sent Events (SSE) です。

本記事では、SSEの概要と、フロントエンドでの実装方法についてまとめます。

SSEは、サーバーからクライアント(主にWebブラウザ)へ、一方向にリアルタイムでデータをプッシュするための仕組みです。
WebSocketと違い、クライアント→サーバーの通信はできませんが、HTTP/1.1ベースで実装がシンプル、サーバー側の負担も比較的軽いのが特徴です。

生成AIチャットアプリでは、AIの回答を「一文字ずつ」や「一文ずつ」ストリーミング表示する際によく使われます。


SSEを受け取る方法はいくつかあります。代表的なものを3つ紹介します。

1. EventSource

EventSourceオブジェクトを使い、サーバーとコネクションを張りっぱなしにしてtext/event-stream形式のデータを受信します。

const eventSource = new EventSource('/sse-endpoint');
eventSource.onmessage = (event) => {
  console.log(event.data); // サーバーからのデータ
};

メリット

  • 実装が簡単で、ブラウザ標準対応
  • 自動で再接続される

デメリット

  • HTTPメソッドはGETのみ(POST不可)
  • カスタムヘッダーが付けられないため、CORSや認証に工夫が必要な場合がある

2. fetch + ReadableStream

fetchでSSEエンドポイントにアクセスし、ReadableStreamでストリームを逐次処理します。
バイナリデータをテキストにデコードし、必要に応じてJSONにパースします。

const response = await fetch('/sse-endpoint');
const reader = response.body.getReader();
const decoder = new TextDecoder('utf-8');
let buffer = '';

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  buffer += decoder.decode(value, { stream: true });
  // bufferを適宜パースして利用
}

メリット

  • POSTやカスタムヘッダーが利用可能
  • 細かい制御や独自プロトコルにも対応しやすい

デメリット

  • 自動再接続などの仕組みは自前で実装が必要
  • 実装がやや複雑

3. Axios

HTTPクライアントライブラリのAxiosを使用してresponseType: 'stream'を指定することでストリームレスポンスを受け取れますが、これはNode.js環境限定です。
ブラウザ環境のXMLHttpRequestのResponseTypeでは'stream'は使えません。

参考:Interface XMLHttpRequest

// Node.jsの場合
const axios = require('axios');
const response = await axios.get('/sse-endpoint', { responseType: 'stream' });
response.data.on('data', (chunk) => {
  console.log(chunk.toString());
});

メリット

  • Node.js環境でのストリーム処理が簡単

デメリット

  • ブラウザ環境ではresponseType: 'stream'が使えない

ブラウザでAxiosを使いたい場合

adapter: 'fetch'を指定することで、2.のfetchと同様の方法でストリームを受け取れます。

参考:Fetch adapter | axios | promise based HTTP client

import axios from 'axios';

const response = await axios.get('/sse-endpoint', {
  adapter: 'fetch'
  // 他のfetchオプションも指定可能
});
// response.bodyはReadableStream

  • SSEは生成AIチャットアプリなどで「リアルタイムにサーバーからデータを受け取る」用途に便利
  • 実装方法は用途や環境に応じて選択(EventSource, fetch, Axios)
  • 認証やPOSTリクエストが必要な場合はfetchが柔軟

SSEを活用して、よりリッチなリアルタイムWeb体験を実現しましょう!


参考





Source link

Views: 0

RELATED ARTICLES

返事を書く

あなたのコメントを入力してください。
ここにあなたの名前を入力してください

- Advertisment -