Server-Sent Events em Go: Quando WebSocket é exagero
Imagine: você está escrevendo um dashboard para monitoramento de servidores. Os dados são atualizados a cada 5 segundos. O cliente deve receber notificações sobre queda de carga. O que você escolheria? WebSocket? Long Polling? E se eu disser que existe uma tecnologia que funciona sobre HTTP comum, não requer bibliotecas adicionais no cliente e é ideal para transmissão unidirecional de dados?
Conheça — Server-Sent Events (SSE). É um protocolo embutido no HTML5, que permite ao servidor enviar dados ao cliente em tempo real através de uma única conexão HTTP. Ao contrário do WebSocket, o SSE funciona apenas em uma direção — do servidor para o cliente. Mas é exatamente isso que o torna ideal para notificações, logs, cotações de ações e qualquer tarefa onde o servidor é a fonte de dados e o cliente é um ouvinte passivo.
Neste artigo, vamos analisar como implementar Server-Sent Events em Go. Você aprenderá como criar um streaming simples, como transmitir eventos personalizados e como lidar com desconexões de clientes. Vamos lá!
Por que Go + SSE é poderoso?
Go é uma linguagem criada para aplicações de rede. Suas goroutines e canais se encaixam perfeitamente no modelo SSE: cada conexão é uma goroutine separada, e os canais garantem a transmissão segura de dados. Além disso, Go é uma linguagem compilada com excelente desempenho. Você pode manter dezenas de milhares de conexões SSE abertas sem grande consumo de memória.
A principal vantagem do SSE sobre o WebSocket é a simplicidade. No cliente, usa-se a API EventSource comum, que funciona em todos os navegadores modernos. Sem bibliotecas adicionais, sem frameworks. A parte do servidor é um handler HTTP comum com os cabeçalhos corretos.
Quando usar SSE?
- Transmissão unidirecional — o servidor envia dados, o cliente apenas recebe.
- Notificações e alertas — sistema de monitoramento, notificações push.
- Streaming de dados — logs, cotações, tweets, notícias.
- Reconexão automática — o navegador restaura a conexão sozinho em caso de queda.
Fundamentos do protocolo Server-Sent Events
Antes de escrever código, vamos entender como o SSE funciona no nível HTTP. Quando o cliente abre uma conexão, o servidor envia cabeçalhos especiais:
Content-Type: text/event-streamCache-Control: no-cacheConnection: keep-aliveDepois disso, o servidor envia dados no formato:
data: Mensagem
Cada mensagem é separada por duas quebras de linha. É possível enviar vários campos:
event: userlogindata: {"username": "alice"}
O campo event define o tipo de evento, e data — seu conteúdo (geralmente JSON). Também existem os campos id (identificador do último evento) e retry (tempo de reconexão em milissegundos).
Escrevendo um servidor SSE em Go
Vamos começar com o mais simples — um servidor que envia a hora atual a cada segundo. Crie o arquivo main.go:
package main
import ( "fmt" "net/http" "time")
func main() { http.HandleFunc("/events", sseHandler) http.ListenAndServe(":8080", nil)}
func sseHandler(w http.ResponseWriter, r *http.Request) { // Configura os cabeçalhos para SSE w.Header().Set("Content-Type", "text/event-stream") w.Header().Set("Cache-Control", "no-cache") w.Header().Set("Connection", "keep-alive")
// Cria um flusher para envio imediato de dados flusher, ok := w.(http.Flusher) if !ok { http.Error(w, "Streaming unsupported", http.StatusInternalServerError) return }
// Loop infinito de envio de eventos for { select { case <-r.Con