Server-Sent Events (SSE) é uma tecnologia que permite a comunicação unidirecional entre o servidor e o cliente em tempo real. SSE é uma alternativa aos WebSockets que oferece várias vantagens, como menor sobrecarga de rede e menor uso de recursos. Neste tutorial, iremos aprender como implementar SSE em Go e compará-lo com WebSockets.
O que é SSE?
SSE é um protocolo de comunicação baseado em HTTP que permite que o servidor envie eventos para o cliente. O cliente se inscreve em um fluxo SSE, que é uma conexão persistente entre o cliente e o servidor. O servidor envia eventos em formato de texto para o cliente, que é capaz de processá-los em tempo real. Os eventos podem ser nomeados e o payload pode ser em formato de texto ou JSON.
Como implementar?
O exemplo a seguir mostra como implementar SSE utilizando Golang, mas não se apegue a linguagem pois pode ser qualquer outra, basta definir os Headers corretos que você será capaz reproduzir.
Back-end (Golang)
package main
import (
"fmt"
"net/http"
"time"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "index.html")
})
http.HandleFunc("/sse", func(w http.ResponseWriter, _ *http.Request) {
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
messageCounter := 0
for {
someMessage := fmt.Sprintf("Message: %v", messageCounter)
eventName := "event: myCustomEvent\n"
payloadMessage := fmt.Sprintf("data: %s\n\n", someMessage)
w.Write([]byte(eventName))
w.Write([]byte(payloadMessage))
time.Sleep(1 * time.Second)
w.(http.Flusher).Flush()
messageCounter++
}
})
http.ListenAndServe(":3333", nil)
}
A rota /sse define os cabeçalhos necessários para enviar eventos SSE. O cabeçalho Content-Type é definido como text/event-stream, Cache-Control é definido como no-cache para evitar o armazenamento em cache e Connection é definido como keep-alive para manter a conexão aberta. Em seguida, o servidor inicia um loop infinito para enviar eventos SSE. O evento é opcional e pode ser usado para especificar o tipo de evento que está sendo enviado. O payload contém os dados que estão sendo enviados.
O uso do
\né obrigatório, você pode observar que uso ele ao definir o nome do evento e payload da mensagem. O SSE vai conseguir interpretar quando essas informações foram definidas após essa quebra de linha, por fim, o\nadicional informa que acabou aquele evento.
Exemplo de como vai ficar no final após a interpretação:
event: myCustomEvent
data: Message: 1
event: myCustomEvent
data: Message: 2
Front-end (HTML + JavaScript)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SSE</title>
</head>
<body>
<h1>SSE - Real Time Messages</h1>
<ul id="messages"></ul>
<script>
const eventSource = new EventSource('/sse');
eventSource.addEventListener('myCustomEvent', event => {
const messagesElement = document.getElementById('messages');
const li = document.createElement('li');
li.innerText = event.data;
messagesElement.appendChild(li);
console.log(event);
});
</script>
</body>
</html>
O código acima é muito simples, basicamente vamos estar recebendo as mensagens que o nosso Back-end vai mandar, e vamos adicionar elas em tela, somente isso.
A instância do EventSource, recebe a URL do endpoint SSE que o servidor está ouvindo (/sse neste caso). Isso estabelece uma conexão persistente entre o cliente e o servidor, permitindo que o servidor envie atualizações em tempo real para o cliente.
Em seguida, é adicionado um ouvinte de eventos para o evento personalizado myCustomEvent, que é enviado pelo servidor. Quando esse evento é recebido, uma nova linha de lista li é criada, contendo o texto da mensagem que foi enviada pelo servidor. A linha de lista é então adicionada ao elemento ul com o id messages, que é onde as mensagens são exibidas na página.
Vantagens e Desvantagens do SSE
SSE tem várias vantagens em relação aos WebSockets. A primeira é que ele é baseado em HTTP e usa a porta HTTP padrão (80), o que significa que ele pode passar por firewalls e proxies sem problemas. Além disso, o SSE requer menos sobrecarga de rede e recursos do servidor do que o WebSocket, porque apenas o servidor pode enviar dados. Isso significa que o servidor não precisa lidar com tantas conexões de saída e, portanto, pode lidar com mais conexões de entrada. Finalmente, o SSE é fácil de implementar, pois é baseado em HTTP e usa o mesmo modelo de programação.
No entanto, o SSE também tem algumas desvantagens. A primeira é que ele só suporta comunicação unidirecional (do servidor para o cliente), o que significa que o cliente não pode enviar dados para o servidor. Além disso, o SSE não é suportado por todos os navegadores e plataformas, o que significa que você precisará testar se o SSE funciona em todos os navegadores e plataformas que você deseja suportar.
Comparação SSE vs WebSockets
Embora SSE e WebSockets possam parecer semelhantes, eles têm algumas diferenças importantes. A principal diferença é que o WebSocket é bidirecional, o que significa que tanto o cliente quanto o servidor podem enviar dados. Isso torna o WebSocket mais adequado para aplicativos em tempo real que exigem interação bidirecional entre o cliente e o servidor, como jogos online ou aplicativos de bate-papo. O SSE, por outro lado, é mais adequado para aplicativos unidirecionais, como feeds de notícias ou atualizações de preços.
Além disso, o WebSocket usa um protocolo de comunicação personalizado que é implementado em um nível mais baixo do que o HTTP. Isso significa que o WebSocket é capaz de suportar recursos avançados, como multiplexação de canais, compressão de dados e autenticação do lado do servidor. O SSE, por outro lado, é implementado como um recurso do HTTP e, portanto, não pode usar esses recursos avançados.


Top comments (0)