Processo de envio de dados do server para o front. É apenas uma via, não é possível enviar de volta dados do front para o server.
Padrão do WHATWG (parte da spec HTML), sobre uma conexão HTTP de longa duração. É a peça de padrão web real usada pelo transporte Streamable HTTP (MCP) do MCP.
Mais detalhes em: https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events
Formato de wire
Content-Type: text/event-stream, corpo texto plano, eventos separados por linha em branco:
data: primeira parte da resposta
data: segunda parte
event: done
data: {"tokens": 42}
Campos possíveis por evento:
data:— payload (múltiplas linhasdata:seguidas são concatenadas com\n)event:— tipo do evento (opcional, defaultmessage)id:— id do evento, usado pra resumabilityretry:— tempo em ms que o cliente espera antes de reconectar
Reconexão automática
Diferencial do SSE nativo (EventSource): se a conexão cai, o browser reconecta sozinho, sem lógica de retry manual. Ele reenvia o header Last-Event-ID com o último id: recebido; o servidor decide se faz replay dos eventos perdidos ou continua do zero.
Limitações
- Unidirecional — cliente não manda nada pela mesma conexão (prompt/input vai por request separado)
- Limite de conexões por domínio em HTTP/1.1 — browsers limitam a ~6 por origin; some com HTTP/2 (multiplexing)
- Só texto — binário precisa base64
EventSourcenativo não suporta headers customizados nem POST — só faz GET, sem body. Pra mandar prompt + histórico (caso de chat), precisa de:fetch+ReadableStreammanual (parsing próprio dodata: ...\n\n, buffer,AbortController), ou- lib
@microsoft/fetch-event-source— mesma API doEventSource(parsing, reconexão,Last-Event-ID) mas usafetchpor baixo, aceitando POST/headers/body. Geralmente a melhor escolha, evita reinventar parsing de SSE.
Uso em chatbots (streaming de resposta tipo ChatGPT)
SSE é o recomendado pra esse caso (é o que OpenAI/Anthropic usam), em vez de WebSocket:
- Unidirecional server→client bate exatamente com o caso de uso
- Roda sobre HTTP puro — passa por load balancers/CDN/proxy corporativo sem drama (WebSocket exige upgrade de conexão)
- Modelo mental bate 1:1 com geração token-by-token — cada
data:é um chunk, evento final (event: doneoudata: [DONE]) sinaliza fim
WebSocket só compensa se precisar de baixa latência bidirecional simultânea (ex: interromper geração + mandar novo input ao mesmo tempo), voice/real-time multimodal, ou stream colaborativo com múltiplos participantes. Cancelamento de geração dá pra fazer com AbortController sem precisar de full duplex.