慣性聚合 関心のあるブログ、ニュース、テクノロジーを効率的に追跡
原文を読む 慣性聚合で開く

おすすめ購読元

博客园 - 司徒正美
V
V2EX
T
Tailwind CSS Blog
有赞技术团队
有赞技术团队
aimingoo的专栏
aimingoo的专栏
Apple Machine Learning Research
Apple Machine Learning Research
IT之家
IT之家
Blog — PlanetScale
Blog — PlanetScale
A
About on SuperTechFans
月光博客
月光博客
T
The Blog of Author Tim Ferriss
宝玉的分享
宝玉的分享
Martin Fowler
Martin Fowler
博客园 - 聂微东
The GitHub Blog
The GitHub Blog
V
Visual Studio Blog
WordPress大学
WordPress大学
酷 壳 – CoolShell
酷 壳 – CoolShell
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python)
サーバーセンティッドイベント(SSE)とは何ですか?2026年向け開発者ガイド
Rahul J · 2026-05-24 · via DEV Community

要約

サーバーセンティッドイベント(SSE) は、平文HTTP上で構築されたサーバー→ブラウザの単向ストリーミングプロトコルです。ブラウザは new EventSource(url) と接続を開き、サーバーはその接続を維持し、必要に応じて data: の行をプッシュします。それだけです。WebSocketのハンドシェイクは不要で、ws://、アップグレードなし。自動的に再接続し、HTTPを話すすべてのプロキシを通じて動作し、2012年以来すべてのブラウザに搭載されています。

サーバー→クライアントのストリーミングが必要で、双方向メッセージングは必要ない場合、SSEは2026年に重要な点のほとんどにおいてWebSocketsを優勝しています。: より少ないコード、シンプルなインフラ、自動再接続、再開可能なための自動イベントID。WebSocketに手を伸ばす唯一の理由は双方向チャットスタイルのトラフィックやバイナリフレームです。

今すぐストリーミングを見たいですか?無料のSSEテスターを開きます、任意のSSEエンドポイントを貼り付け、イベントがライブで届くのを観察します。

30秒のマインドモデル

[ Browser ]  ──── GET /events ───►  [ Server ]
              ◄── HTTP 200, keep alive
              ◄── data: hello\n\n
              ◄── data: world\n\n
              ◄── data: ...

フルスクリーンモードに入ります フルスクリーンモードを終了

これは永続的なHTTP GETであり、決して閉じることがなく、レスポンスボディには特定のテキスト形式があります。MIMEタイプはtext/event-streamです。改行ごとにonmessageにイベントをフラッシュします。ブラウザがフレーミング、パース、再接続を処理します—あなたはeventSource.onmessage = ...を書けば終わりです.

最も小さな可能な例

サーバー(Node.js — ライブラリ不要):

import http from 'node:http';

http.createServer((req, res) => {
  if (req.url !== '/events') {
    res.writeHead(404).end();
    return;
  }

  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
  });

  let n = 0;
  const interval = setInterval(() => {
    res.write(`data: tick ${++n}\n\n`);
  }, 1000);

  req.on('close', () => clearInterval(interval));
}).listen(3000);

フルスクリーンモードに入る フルスクリーンモードから退出する

クライアント(どこでも — <script> タグを含む):

const es = new EventSource('/events');
es.onmessage = (e) => console.log('got:', e.data);
es.onerror = () => console.warn('disconnected, browser will retry');

フルスクリーンモードに入る フルスクリーンモードから退出する

サーバーを実行し、クライアントをブラウザコンソールに貼り付けると、20行以下のコードでストリーミングが利用可能になります。ビルドステップなし。ライブラリなし。アップグレード交渉なし. それが全ての提案です.

2026年にSSEが低評価されている理由

「リアルタイム」と聞いただけでチームがWebSocketに無意識に手を伸ばし、その後1週間をプロキシのタイムアウト、スタickyセッション、ALBアップグレードヘッダーのデバッグに費やすことがあります。使用例の半分はサーバー→クライアントのみでした——フィード、通知ドロワー、ビルドログ、ライブカウンターです。これはSSEの領域です。

SSEで無料で得られるもの、WebSocketで自分で作る必要があるものは以下の通りです:

1. 自動再接続。 接続が切断されると、ブラウザは約3秒間待って再接続します。これにはコードを書く必要はありません。WebSocketsを使うと、キャリア全体でプロジェクトごとに同じバックオフループを書き続ける必要があります.

2. イベントIDと再開. サーバーがid: 42\nを送信すると、ブラウザは次回の再接続でヘッダーとしてLast-Event-ID: 42を送信します。サーバーはそこから再開できます。これはSSEがビルドログ、AIストリーミング、監査フィードに優れている機能です。WebSocketsを使えば、自分でカスタムプロトコルを設計できます.

3. 標準HTTPの使用です. SSEはGETAccept: text/event-streamです。プロキシのすべて、CDNのすべて、WAFのすべて、リバースプロキシのすべてがそれを理解します(ただし、下記の注意点があります)。クッキー、AuthorizationCORS、圧縮 — すべて正常に動作しています。WebSocketsにはアップグレードのダンスが必要で、プロキシはしばしばそれを間違って扱います。

4. 言い訳はしない。テキストのみ、行区切りで。できますcurlSSEエンドポイントに接続して、ターミナルでストリームを読み取ってみてください。WebSocketでそれを試してみてください。

curl -N -H "Accept: text/event-stream" https://api.example.com/events

フルスクリーンモードに入る フルスクリーンモードを終了する

SSEフレームの構造

フォーマットは非常にシンプルだが、人々を混乱させることがある。各イベントは一つ以上の行で構成され、二つの改行で終了する(空行):

event: user-joined
id: 423
retry: 5000
data: {"userId":42,"name":"Ada"}

data: simple message
data: continuation of the same event

フルスクリーンモードに入る フルスクリーンモードから退出する

  • data: — これがペイロードである。同じイベント内の複数のdata:行は、\nで結合される.
  • event: — イベントを設定es.addEventListener('user-joined', ...)を聞く。省略するとonmessageが発火します
  • id: — 再接続時にブラウザがLast-Event-IDとして送り返すものです
  • retry: — 再接続する前に待つミリ秒数です

の空白行は必須です。二つ目を忘れる\nはSSEのバグ第1位です。プロキシ内のイベントバッファーとクライアントには何も見えません。

SSEとWebSocketsとロングポーリングの使用時期

これはあなたが必要とする唯一の決定木です:

SSEを使用するのは次のような場合:

  • トラフィックがサーバー→クライアントのみ(通知、フィード、ダッシュボード、ログ、AIトークンストリーミング)
  • 自動再接続を記述せずに実現したい
  • テキストストリーミング(JSON、Markdownチャンク、ログ行)
  • デバッグしたい場合curl

WebSocketを使用するのは次の場合:

  • 双方向で高頻度のトラフィックがある場合(チャット、協力編集、マルチプレイヤーゲーム)
  • バイナリフレームが必要な場合(オーディオ/ビデオ、カスタムプロトコル)
  • クライアント→サーバーメッセージの100ミリ秒未満のラウンドトリップが必要な場合

ロングポーリングを使用する場合:

  • 上記の両方を壊すインフラに詰まっている場合(2026年では稀ですが、積極的な企業プロキシの背後で発生することがあります)

両側のコードでの完全なクラッシュは、SSE と WebSockets とロングポーリングの深掘りにあります。

三つの生産性の落とし穴

これらは、SSEを初めてリリースするたびに各チームに影響を与えるバグです.

1. プロキシバッファリングが致命的です

Nginxはデフォルトでレスポンスをバッファリングします。あなたのres.writeがバッファに入ります;クライアントは数分間何も見ません。2つの修正方法があります。両方を行ってください:

サーバーのレスポンスヘッダー:

X-Accel-Buffering: no

フルスクリーンモードに入る フルスクリーンモードから退出する

Nginxの設定:

proxy_buffering off;
proxy_cache off;
proxy_read_timeout 24h;

フルスクリーンモードを開始 フルスクリーンモードを終了

Cloudflareはバッファリングが多すぎる—SSEエンドポイントをキャッシュされないルートに置くか、Cloudflareに対応したストリーミング設定を使用する必要がある

2. ブラウザの1オリジンあたり6接続の制限

ブラウザは1オリジンあたり約6つのHTTP/1.1オープン接続に制限されています。あなたのアプリが接続を開く場合EventSource とユーザーがさらに5つのタブを開くと、7番目のタブが接続スロットがないためフリーズします。2つの解決策:

  • HTTP/2 または HTTP/3 を使用 — 接続マルチプレクシングは、1つのTCP接続で数百のストリームを意味します。これは現代的な解決策です.
  • タブ間で BroadcastChannel または SharedWorker を通じて連携 — 一つのタブが EventSource を保持し、兄弟タブにイベントをブロードキャストします.

3. 心拍とアイドルタイムアウト

WebSocketと同じトラップ:ロードバランサーがアイドル接続を閉じます。AWS ALBのデフォルトは50秒です。15-30秒ごとにコメント行を送信します:

setInterval(() => res.write(':keepalive\n\n'), 15000);

フルスクリーンモードに入る フルスクリーンモードから退出する

:で始まる行は仕様に従ってコメントです — それらは接続を温めながら、トリガーを発火させませんonmessage はクライアント上で動作します。

認証とSSE

EventSource には一つ煩わしい制限があります:カスタムヘッダーを構築時に設定することができません。何もAuthorization: Bearer ...。あなたの選択肢は:

1. クッキー(ブラウザアプリケーションに推奨) — ブラウザが自動的に送信します。withCredentials: trueを使用し、CORSであなたのオリジンを許可してください。

const es = new EventSource('/events', { withCredentials: true });

フルスクリーンモードを開始 フルスクリーンモードを終了

2. クエリストリングトークン — 効作しますが、トークンはサーバーログに残ります

3. fetch + ReadableStream のパターンEventSourcefetch で削除し、 は行動を起こしませんカスタムヘッダーを受け入れる。オートリコンネクトを失い、自分でフォーマットをパースしなければならないが、トークン認証を持つ現代のアプリにとって正しい選択だ。

const res = await fetch('/events', {
  headers: { Authorization: `Bearer ${token}` },
});
const reader = res.body.getReader();
// ... parse text/event-stream chunks manually

フルスクリーンモードに入る フルスクリーンモードを終了する

図書館のような@microsoft/fetch-event-sourceこれをあなたのために行い、ほとんどの現代のAIストリーミングクライアントが内部で使用しています。

SSEはAIストリーミングを動力している

過去2年間、ChatGPTやClaude、あるいは他のAIチャットUIを使ったことがあるなら、SSEの動作を見てきました。サーバーはトークンが生成されるたびにストリーミングします:

data: {"choices":[{"delta":{"content":"Hello"}}]}

data: {"choices":[{"delta":{"content":" world"}}]}

data: [DONE]

フルスクリーンモードを開始 フルスクリーンモードを終了

Anthropic社、OpenAI社、Google社のストリーミングAPIはすべてSSE(または非常に似たカスタムイベントストリーム形式)を使用しています。SSEを知っていれば、他のウェブプロトコルと同じツールでAIストリーミングエンドポイントをデバッグできます。

SSEエンドポイントのテスト方法

使用する順序に従って三つの方法があります:

1. curl -N — バッファーフラグなし。最も速い健全性チェック。

curl -N -H "Accept: text/event-stream" https://api.example.com/events

フルスクリーンモードに入る フルスクリーンモードから退出する

2. ブラウザ内のSSEテスター — URLを貼り付け、イベントをリアルタイムで確認し、ヘッダーを確認し、再接続の挙動を確認します。こちらで無料で1つ入手、インストール不要です。

3. ブラウザデベロッパーツール → ネットワーク → イベントストリームタブ — アプリが開かれると、パースされたイベントストリームをリアルタイムで確認できます。Chromiumベースのブラウザにはそれ専用のタブがあります。

普通の誤解

  • "SSEは死に、WebSocketsがそれを置き換えました。" WebSocketsは成長したが、SSEはどこにも行かなかった——AIストリーミング、GitHub Actionsログ、Vercelデプロイログ、Stripeウェブフック(まあ、技術的にはSSEではないが同じ考え方だ)、そして日々使用するほとんどの「通知」機能を動かしている
  • 「SSEはHTTP/2と動作しない」 HTTP/2ではより良い動作する——6接続の制限がないし、すべてのストリームがマルチプル化される
  • "SSEはテキストのみなのでバイナリを送信できません。" その通りですが、JSONフィールドで小さなバイナリペイロードをbase64でエンコードするのは問題ありません。実際のバイナリストリームの場合は、WebSocketを使用するか、単にHTTPダウンロードを使うべきです.
  • "SSEにはping/pongがありません。" 15秒ごとにコメント行(:heartbeat\n\n)を送信します。完了です.

FAQ

SSEは長時間ポーリングと同じですか?
番号長ポーリングはクライアントがリクエストをし、サーバーがデータがあるまでそれを開いたままにし、サーバーが応答し、クライアントが別のリクエストを行います。SSEは一つのリクエストが永遠に開いたまま、サーバーがデータがあるときにプッシュします。長ポーリングは毎回接続を再開します。SSEはしません。

モバイルブラウザでSSEが動作しますか?
はい、iOSのSafari、Chrome Android、Firefox Mobileで完全にサポートしています。自動再接続はセルラーのハンドオフをうまく処理します。

React / Vue / Svelte / Solid で SSE を使えますか?
はい、どのようなサブスクリプションを使うかのように使えます。EventSourceuseEffect(同等のもの)内でスピンアップし、クリーンアップ時に閉じ、各メッセージで状態を設定します。

サーバーが同時に処理できる SSE 接続の最大数はいくつですか?
Node.jsと賢明な設定で、各プロセスあたり数万もの接続が可能です—接続はほとんどアイドル状態で、それぞれ数KBのRAMを消費します。実際の上限として、各プロセスあたり約32k-65kのオープンファイル記述子と比較してください。

使うべきですかEventSourceまたはfetchプラスReadableStream
使用EventSourceもしクッキー認証があなたにとってうまくいくなら(シンプルで無料の自動再接続)。使用fetch もし Authorization ヘッダーやカスタムリクエスト挙動が必要な場合、再接続を処理するライブラリを組み込んでください。


元々は AllDevToolsHub で公開されました。プライバシーを重視した無料のブラウザベースの開発ツール 250種類以上 — SSE テスター、WebSocket テスター、JWT デコーダーなど — については、alldevtoolshub.com をご覧ください。