A tecnologia subestimada de Server-Sent Events (SSE)
(igorstechnoclub.com)Server-Sent Events (SSE) são subestimados
- A maioria dos desenvolvedores conhece WebSockets, mas SSE é uma alternativa mais simples e muitas vezes ignorada.
- SSE estabelece um canal de comunicação unidirecional do servidor para o cliente por HTTP.
- Ao contrário da conexão bidirecional dos WebSockets, SSE mantém uma conexão HTTP aberta para atualizações do servidor para o cliente.
Por que SSE é subestimado
- Popularidade do WebSocket: o recurso de comunicação full-duplex dos WebSockets ofusca a abordagem mais simples do SSE.
- Percepção sobre limitações: sua natureza unidirecional pode parecer limitante, mas é suficiente para muitos casos de uso.
Principais pontos fortes do SSE
-
Simplicidade de implementação
- Aproveita o protocolo HTTP padrão, eliminando a complexidade de gerenciar conexões WebSocket.
-
Compatibilidade com infraestrutura
- Funciona perfeitamente com a infraestrutura HTTP existente:
- balanceadores de carga
- proxies
- firewalls
- servidores HTTP padrão
- Funciona perfeitamente com a infraestrutura HTTP existente:
-
Eficiência no uso de recursos
- Menor consumo de recursos em comparação com WebSockets:
- natureza unidirecional
- uso de conexões HTTP padrão
- sem necessidade de manutenção contínua de sockets
- Menor consumo de recursos em comparação com WebSockets:
-
Reconexão automática
- Suporte nativo do navegador:
- tratamento de interrupções de conexão
- tentativas automáticas de reconexão
- experiência em tempo real mais resiliente
- Suporte nativo do navegador:
-
Semântica clara
- O padrão de comunicação unidirecional garante:
- separação clara de responsabilidades
- fluxo de dados intuitivo
- lógica de aplicação simplificada
- O padrão de comunicação unidirecional garante:
Aplicações práticas
- feeds de notícias em tempo real e atualizações sociais
- cotações de ações e dados financeiros
- barras de progresso e monitoramento de tarefas
- streaming de logs do servidor
- edição colaborativa (para atualizações)
- rankings de jogos
- sistemas de rastreamento de localização
Exemplo de implementação
Lado do servidor (Flask)
- A rota
/streamlida com a conexão SSE. generate_random_data()gera continuamente eventos formatados.- O tipo MIME
text/event-streamsinaliza o protocolo SSE. stream_with_contextmantém o contexto da aplicação Flask.
Lado do cliente (JavaScript)
- O objeto
EventSourcegerencia a conexão SSE. - O handler
onmessageprocessa os eventos recebidos. onerrorlida com problemas de conexão.- O navegador cuida da reconexão automática.
Limitações e considerações
-
Comunicação unidirecional
- Possível apenas do servidor para o cliente
- A comunicação do cliente para o servidor exige requisições HTTP separadas
-
Suporte de navegadores
- Bem suportado em navegadores modernos
- Navegadores antigos podem exigir polyfill
-
Formato dos dados
- Suporta principalmente dados baseados em texto
- Dados binários exigem codificação (ex.: Base64)
Boas práticas
-
Tratamento de erros
- Trate erros de conexão com
eventSource.onerror.
- Trate erros de conexão com
-
Gerenciamento de conexão
- Encerre e limpe a conexão quando concluir.
-
Estratégia de reconexão
- Defina um número máximo de tentativas e implemente a lógica de reconexão.
Exemplo real: implementação do ChatGPT
- Modelos modernos de linguagem de grande porte (LLM) usam SSE para fornecer respostas em streaming.
- Principais padrões:
- retorno do cabeçalho
content-type: text/event-stream - streaming de blocos de dados separados por
\r\n\r\n
- retorno do cabeçalho
Conclusão
- SSE oferece uma solução elegante para comunicação em tempo real entre servidor e cliente.
- Sua simplicidade, eficiência e integração com a infraestrutura existente fazem dele uma escolha adequada para muitas aplicações.
- WebSockets continuam úteis para comunicação bidirecional, mas SSE oferece uma solução mais focada e apropriada para cenários de streaming de dados unidirecional.
5 comentários
Implementei a OpenAI via REST e usei SSE na prática.
Pretendo adotá-lo sempre que houver necessidade de comunicação unidirecional.
No caso de SSE, ele costuma não ser bloqueado por equipamentos de segurança (como WAF ou segurança inteligente), mas com frequência encontro casos em que o streaming por quebras de linha não funciona. (On-premises) É como se, no meio do caminho, recebessem toda a resposta primeiro e depois a enviassem de uma vez só.
É realmente uma pena que o OpenAPI não ofereça suporte a SSE
É realmente uma ótima forma de implementar comunicação bidirecional em um ambiente NAT.
Comentários do Hacker News
Mercure é um protocolo aberto baseado em SSE, usado como alternativa a soluções baseadas em WebSockets. O Mercure funciona em torno de um hub independente que mantém conexões SSE persistentes com os clientes e fornece uma API HTTP simples que pode ser usada por aplicativos de servidor e clientes. O Mercure adiciona recursos como mecanismo de autenticação baseado em JWT, assinatura de vários tópicos em uma única conexão, histórico de eventos e ajuste automático de estado quando ocorrem problemas de rede
A grande desvantagem do SSE é o limite no número máximo de conexões quando não se usa HTTP/2. Isso pode ser um problema ao abrir várias abas, já que o limite por navegador pode ser baixo
No CLI da Doppler, usaram SSE para implementar uma função de reinicialização automática. Os eventos são recebidos do servidor via SSE, as informações mais recentes de segredos são buscadas e então injetadas no processo da aplicação. O motivo para escolher SSE em vez de WebSockets foi evitar adicionar dependências extras à aplicação em Golang. Para resolver problemas de timeout HTTP, foi necessário enviar eventos de "ping" de forma intermitente
A natureza unidirecional do SSE pode parecer limitante, mas em muitos casos é suficiente. As principais limitações do SSE são ser apenas para texto e a limitação de conexões do navegador em HTTP/1.1. Ao usar HTTP/2 ou superior, o limite de conexões deixa de ser um problema. Quando desempenho é importante, pode-se optar por uma solução mais flexível e com menos overhead usando fetch e ReadableStream
Por causa da simplicidade do SSE, muitos desenvolvedores acabam não usando uma implementação adequada e fazem o parsing dos chunks de dados com expressões regulares. Isso pode causar problemas porque o SSE oferece suporte a comentários no stream
Data-star.dev é uma biblioteca frontend focada em fazer streaming de respostas de hipermídia via SSE. Foi desenvolvida usando Go e NATS como tecnologias de backend e é compatível com todas as implementações de SSE
SSE não é subestimado. Na verdade, está sendo usado pela Open AI para streaming de conclusões. Implementar SSE em uma base de código ReactJS foi difícil, e na época o Axios não dava suporte, então foi preciso usar o fetch nativo
Quando implementaram SSE em um projeto web, ao abrir mais de 6 abas o site parava de funcionar. O Firefox conta as conexões SSE dentro do limite máximo de 6 conexões por host, e isso bloqueia requisições adicionais
SSE é subestimado quando funciona bem. Em um projeto em andamento, estão enfrentando dificuldades com problemas de autenticação e de keep-alive em túneis. Isso não é um problema do protocolo, mas encontrar a solução tem sido difícil