SSE — o que é, Server-Sent Events e streaming unidirecional

Autor: IT Sectr Publicado: 2026-06-02 Tempo de leitura: 8 min

SSE (Server-Sent Events) é um padrão W3C que permite ao servidor enviar dados em streaming para o cliente através de uma única conexão HTTP no modo unidirecional. Ao contrário do WebSocket, o SSE funciona sobre HTTP normal e não requer um protocolo especial ou biblioteca no lado do cliente. De acordo com a especificação W3C HTML Living Standard (2025), a API EventSource é suportada em todos os navegadores modernos, incluindo Chrome, Firefox, Safari e Edge.

Principais pontos

  • SSE é um padrão para transferência unidirecional de dados do servidor para o cliente através de uma conexão HTTP.
  • API EventSource é uma interface de navegador integrada para receber SSE sem bibliotecas externas.
  • Reconexão automática — o navegador restaura automaticamente a conexão quando ela cai.
  • Protocolo de texto — os dados são transmitidos no formato text/event-stream com um formato de texto simples.
  • Comunicação unidirecional — SSE é adequado para notificações, feeds de notícias, tickers e monitoramento, mas não para chats.

O que é SSE?

SSE (Server-Sent Events) é uma tecnologia que permite a um servidor web enviar dados ao cliente a qualquer momento após estabelecer uma conexão. É padronizada pela WHATWG como parte do HTML Living Standard e usa o tipo MIME text/event-stream. O SSE suporta transmissão de dados de texto com a capacidade de especificar um identificador de mensagem, tipo de evento e atraso de reconexão.

Ao contrário do WebSocket, que requer um protocolo bidirecional e uma solicitação de upgrade, o SSE funciona sobre HTTP normal. O servidor define o cabeçalho Content-Type: text/event-stream, envia dados em pedaços e mantém a conexão aberta. O cliente recebe os dados através da API EventSource do navegador, que analisa automaticamente o stream e gera eventos.

De acordo com o CanIUse (2025), a API EventSource é suportada em 97,5% dos navegadores globalmente. Não é suportada no Internet Explorer e em alguns navegadores móveis (Samsung Internet anterior à versão 7.0). Para esses casos, existem polyfills que emulam o EventSource via XHR streaming. O SSE não funciona com HTTP/1.1 pipelining, mas é totalmente compatível com HTTP/2 server push.

História e padronização

SSE foi proposto como parte da especificação HTML5 em 2009 sob o nome Server-Sent DOM Events. A primeira implementação apareceu no Opera 9.0, depois no Firefox 6.0 (2011), Chrome 9.0 (2011) e Safari 5.0 (2010). Em 2015, a especificação foi movida para uma seção separada do HTML Living Standard. Apesar de uma década de história, o SSE continua menos popular que o WebSocket devido à sua natureza unidirecional.

Como funciona o SSE

O funcionamento do SSE é o seguinte: o cliente cria uma instância do EventSource com a URL do endpoint do servidor. O navegador envia uma solicitação GET com o cabeçalho Accept: text/event-stream. O servidor responde com status 200 OK e o cabeçalho Content-Type: text/event-stream, depois começa a enviar dados no formato event-stream. A conexão permanece aberta até que o servidor envie um sinal de término ou o cliente chame close().

No lado do servidor, os dados são enviados em pedaços (chunked transfer encoding). Cada pedaço de dados é uma mensagem de texto composta por linhas de campos (event, data, id, retry). O servidor pode enviar mensagens a qualquer momento, tornando o SSE ideal para notificações e atualizações de status. A conexão não requer troca constante de pacotes heartbeat (como o WebSocket), embora o campo retry controle a frequência de reconexão.

De acordo com testes de desempenho (2024), o SSE fornece uma taxa de transferência de até 10.000 mensagens por segundo por conexão com um tamanho de mensagem de 256 bytes. No lado do servidor, cada conexão SSE consome aproximadamente 5–10 KB de memória, permitindo que um servidor suporte mais de 50.000 conexões simultâneas com 1 GB de RAM. Isso é significativamente menos que o WebSocket devido à ausência de um protocolo binário.

Formato event-stream

O formato text/event-stream é um protocolo de texto simples onde cada mensagem consiste em campos nomeados separados por caracteres de nova linha. Cada campo tem o formato “NomeDoCampo: valor”. As mensagens são separadas por dois caracteres de nova linha (\n\n).

Campos suportados: event (tipo de evento, padrão message), data (string de dados, pode ser multilinha), id (identificador do último evento, armazenado em Last-Event-ID), retry (tempo de reconexão em milissegundos). Comentários começam com dois pontos (:) e são ignorados pelo parser, mas podem ser usados para heartbeat.

CampoObrigatórioFinalidade
eventNãoTipo de evento (message por padrão)
dataSimString de dados da mensagem
idNãoIdentificador de evento para Last-Event-ID
retryNãoAtraso de reconexão em ms

Exemplo de event-stream

text
: heartbeat comment
event: update
data: {"user": "Alice", "action": "typing"}
id: 1001

event: notification
data: {"type": "info", "text": "New version available"}
data: {"type": "action", "url": "/upgrade"}
retry: 3000

event: close
data: Session ended

API EventSource no cliente

A API EventSource é uma interface de navegador integrada para receber SSE. Para criar uma conexão, basta chamar o construtor com a URL do endpoint. O EventSource estabelece automaticamente a conexão, lida com a reconexão e analisa as mensagens recebidas em eventos JavaScript.

Eventos do EventSource: open (conexão estabelecida), message (mensagem recebida sem evento especificado), error (erro de conexão). Para eventos personalizados (event: custom), você pode usar addEventListener com o nome do evento. O EventSource envia automaticamente o cabeçalho Last-Event-ID ao reconectar, permitindo que o servidor retome o stream de onde foi interrompido.

De acordo com a documentação MDN (2025), o EventSource suporta CORS e transmissão de credenciais (withCredentials). O EventSource não é adequado para enviar cabeçalhos personalizados ou corpos de requisição — é necessária uma implementação manual via fetch + ReadableStream. O EventSource não suporta dados binários — apenas texto e JSON.

Código JavaScript do lado do cliente

js
const eventSource = new EventSource('/api/events/stream');

eventSource.addEventListener('open', () => {
    console.log('Conexão SSE estabelecida');
});

eventSource.addEventListener('message', (event) => {
    const data = JSON.parse(event.data);
    console.log('Recebido:', data);
    renderUpdate(data);
});

eventSource.addEventListener('notification', (event) => {
    const notification = JSON.parse(event.data);
    showNotification(notification.text);
});

eventSource.addEventListener('error', (error) => {
    console.error('Erro SSE:', error);
    // O navegador reconecta automaticamente
});

// Fechar conexão
eventSource.close();

SSE vs WebSocket: comparação

SSE e WebSocket são tecnologias diferentes para comunicação em tempo real, cada uma com seus pontos fortes. O WebSocket é adequado para troca bidirecional de dados (chats, jogos, edição colaborativa), enquanto o SSE é para fluxos unidirecionais do servidor para o cliente (notificações, feeds de notícias, tickers).

A principal diferença é que o WebSocket requer uma solicitação de upgrade de HTTP/1.1 para o protocolo WebSocket (ws://), que pode ser bloqueada por proxies corporativos. O SSE funciona sobre HTTP normal, passa por qualquer proxy e não requer configuração especial do servidor. O SSE também é mais simples de implementar — o servidor não precisa de uma biblioteca adicional, apenas formar corretamente a resposta HTTP.

De acordo com testes comparativos (2024), em um único processo de servidor, o SSE suporta 30–50% mais conexões que o WebSocket devido ao protocolo mais simples. No entanto, o SSE tem latência maior (50–200 ms contra 10–50 ms do WebSocket) porque o SSE usa HTTP fragmentado em vez de um fluxo bidirecional completo com quadros binários.

CaracterísticaSSEWebSocket
DireçãoServidor → clienteBidirecional
ProtocoloHTTP (text/event-stream)ws:// / wss:// (RFC 6455)
Navegadores97,5% (EventSource integrado)97% (WebSocket integrado)
DadosApenas texto / JSONTexto + binário (Blob, ArrayBuffer)
ProxyPassa por qualquer proxyRequer configuração de proxy
ReconexãoAutomática (navegador)Implementação manual
HistóricoLast-Event-IDSem histórico integrado

Como implementar SSE no servidor

Implementar SSE no servidor não requer bibliotecas — basta definir os cabeçalhos HTTP corretos e enviar dados no formato text/event-stream. Vamos ver um exemplo em Node.js usando o módulo http integrado. O servidor define os cabeçalhos Content-Type e Cache-Control, depois envia mensagens a cada N segundos.

De acordo com o MDN Web Docs (2025), os cabeçalhos necessários para SSE são: Content-Type: text/event-stream, Cache-Control: no-cache e Connection: keep-alive. Sem Cache-Control, o navegador pode armazenar em cache o stream SSE, o que interromperá a entrega. Connection: keep-alive indica explicitamente ao navegador que mantenha a conexão aberta.

Código do servidor em Node.js

js
const http = require('http');

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

    let eventId = 0;
    const interval = setInterval(() => {
        eventId++;
        res.write(`id: ${eventId}\n`);
        res.write(`event: update\n`);
        res.write(`data: {"time": "${new Date().toISOString()}", "id":${eventId}}\n\n`);
    }, 2000);

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

SSE em Python (Flask)

python
from flask import Response, Flask
import time
import json

app = Flask(__name__)

@app.route('/stream')
def stream():
    def generate():
        event_id = 0
        while True:
            event_id += 1
            data = json.dumps(
                {'ticker': 'AAPL', 'price': 150.25})
            yield f'id: {event_id}\nevent: price\ndata: {data}\n\n'
            time.sleep(1)
    return Response(generate(),
        mimetype='text/event-stream')

SSE em aplicativos móveis

O uso de SSE em aplicativos móveis é limitado pela falta de uma implementação nativa do EventSource para iOS e Android. Em plataformas móveis, o SSE é implementado através de bibliotecas de terceiros: no iOS — via URLSession com NSURLProtocol, no Android — via OkHttp com suporte SSE (okhttp-sse). Para React Native e Flutter, existem pacotes que emulam o EventSource.

No iOS, a implementação nativa de SSE é possível via URLSessionDataDelegate. Ao receber dados no método urlSession(_:dataTask:didReceive:), o aplicativo acumula um buffer e analisa o formato event-stream manualmente. De acordo com o blog de desenvolvimento iOS (2024), o consumo de bateria com SSE no iOS é 40% menor do que com uma conexão WebSocket constante devido à ausência de pacotes heartbeat.

No Android, o OkHttp fornece a classe EventSource.Factory para se inscrever em streams SSE. Os aplicativos Android podem usar SSE para notificações quando o FCM não está disponível, ou para sincronização de dados em segundo plano. O SSE no Android funciona bem com o WorkManager para tarefas em segundo plano de longa duração. De acordo com a documentação do OkHttp (2025), o okhttp-sse suporta reconexão automática com um listener personalizado.

Perguntas frequentes

Como o SSE difere do WebSocket?

SSE é transmissão unidirecional (servidor → cliente) sobre HTTP, não requer bibliotecas no cliente. WebSocket é transmissão bidirecional com protocolo binário. SSE é mais simples de implementar, WebSocket é adequado para tarefas onde o cliente também envia dados.

O SSE suporta dados binários?

Não, o SSE transmite apenas dados de texto. Para dados binários (imagens, áudio), é necessária a codificação Base64, que aumenta o tamanho em 33%. Para fluxos binários, é melhor usar WebSocket.

Como o SSE lida com quedas de conexão?

EventSource reconecta automaticamente quando ocorre uma queda. O tempo de atraso é definido pelo campo retry no stream (padrão 1000 ms). Ao reconectar, o navegador envia o cabeçalho Last-Event-ID, permitindo que o servidor retome o stream de onde foi interrompido.

Quantas conexões SSE um navegador pode manter?

Cada navegador tem um limite no número de conexões HTTP simultâneas com um domínio. Para HTTP/1.1 — 6–8 conexões por domínio, para HTTP/2 — até 100. O SSE usa uma conexão, portanto não há concorrência com outras solicitações.

Posso usar SSE para chat?

SSE é adequado apenas para receber mensagens (entrada). Para enviar mensagens (saída), é necessária uma requisição HTTP separada (POST). Para um chat completo, é mais conveniente usar WebSocket ou Socket.IO com comunicação bidirecional em uma única conexão.

Resumo

  • SSE é um padrão para transferência unidirecional de dados do servidor para o cliente através de uma conexão HTTP comum sem bibliotecas adicionais.
  • API EventSource é uma interface de navegador integrada suportada por 97,5% dos navegadores modernos.
  • Protocolo de texto simples text/event-stream com campos event, data, id e retry.
  • Reconexão automática com suporte a Last-Event-ID para retomar o stream de onde foi interrompido.
  • Eficiência — SSE suporta mais conexões de servidor (50.000+) em comparação com WebSocket devido ao protocolo mais simples.
  • Em plataformas móveis o SSE é implementado via OkHttp (Android) ou URLSession (iOS) com análise manual do stream.
  • Para fluxos unidirecionais (notificações, feeds, tickers) escolha SSE, para comunicação bidirecional — WebSocket ou Socket.IO.

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também