Noções Básicas de Tempo Real
10 exemplos para escolher entre WebSocket, SSE e long-polling - 7 básicos e 3 intermediários.
Busque em todas as páginas da documentação
10 exemplos para escolher entre WebSocket, SSE e long-polling - 7 básicos e 3 intermediários.
Estes exemplos assumem Node.js 24.18.0 e um servidor HTTP já em execução (Express 5, Fastify 5 ou node:http puro).
npm install ws
npm install -D @types/wsPara detalhes de implementação, consulte Biblioteca ws, Server-Sent Events e Socket.IO.
| Protocolo | Direção | Transporte | Reconexão | Complexidade |
|---|---|---|---|---|
| WebSocket | Bidirecional | Upgrade TCP | Manual | Médio |
| SSE | Servidor para cliente | Stream HTTP | Automática | Baixa |
| Long-poll | Servidor para cliente | Requisição HTTP | Manual | Mais baixa |
Use WebSocket quando:
- O cliente envia mensagens frequentemente (chat, jogos, colaboração)
- A latência deve ser < 50ms de ida e volta
- Dados binários bidirecionais (áudio, partes de arquivos)
- O estado da conexão importa (presença, indicadores de digitação)Use SSE quando:
- O servidor envia atualizações; o cliente envia apenas via HTTP normal
- Feeds ao vivo (preços de ações, placares esportivos, logs)
- Streams de notificação
- Você quer reconexão automática do navegador// Cabeçalhos de resposta SSE
res.writeHead(200, {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
Connection: "keep-alive",
});
res.write("data: {\"price\": 142.50}\n\n");EventSource do navegador lida com a reconexão automaticamenteUse long-polling quando:
- A infraestrutura bloqueia WebSocket (proxies corporativos raros)
- Necessidade de notificação extremamente simples
- Fallback para Socket.IO (tratado automaticamente)| Caso de uso | Melhor escolha | Por quê |
|---|---|---|
| Aplicação de chat | WebSocket | Bidirecional, baixa latência |
| Visualizador de logs ao vivo | SSE | Push do servidor, reconexão automática |
| Edição colaborativa | WebSocket | Sincronização de estado bidirecional |
| Ticker de ações | SSE | Push unidirecional, amigável a HTTP |
| Jogo multiplayer | WebSocket | Bidirecional, suporte a binário |
| Notificação de e-mail (ícone) | SSE ou polling | Infrequente, unidirecional |
Ciclo de vida do WebSocket:
1. Cliente envia requisição HTTP Upgrade
2. Servidor responde 101 Switching Protocols
3. Conexão TCP persistente estabelecida
4. Frames trocados bidirecionalmente
5. Um dos lados envia frame de fechamento
6. Conexão terminada
Ciclo de vida do SSE:
1. Cliente abre GET HTTP (EventSource)
2. Servidor transmite text/event-stream
3. Conexão permanece aberta
4. Servidor envia linhas data:
5. Em caso de desconexão, o navegador reconecta automaticamente// WebSocket: valide durante o upgrade
server.on("upgrade", (req, socket, head) => {
const token = new URL(req.url!, "http://localhost").searchParams.get("token");
if (!isValid(token)) {
socket.write("HTTP/1.1 401 Unauthorized\r\n\r\n");
socket.destroy();
return;
}
wss.handleUpgrade(req, socket, head, (ws) => wss.emit("connection", ws, req));
});import express from "express";
import { createServer } from "node:http";
import { WebSocketServer } from "ws";
const app = express();
const server = createServer(app);
const wss = new WebSocketServer({ noServer: true });
server.on("upgrade", (req, socket, head) => {
if (req.url?.startsWith("/ws")) {
wss.handleUpgrade(req, socket, head, (ws) => {
wss.emit("connection", ws, req);
});
}
});
wss.on("connection", (ws) => {
ws.on("message", (data) => ws.send(`echo: ${data}`));
});
server.listen(3000);import Fastify from "fastify";
const app = Fastify();
app.get("/events", async (req, reply) => {
reply.raw.writeHead(200, {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
Connection: "keep-alive",
});
const interval = setInterval(() => {
reply.raw.write(`data: ${JSON.stringify({ time: Date.now() })}\n\n`);
}, 1000);
req.raw.on("close", () => clearInterval(interval));
});reply.raw para controle direto do stream no FastifyAntes de 1000 conexões simultâneas, planeje para:
- Sessões fixas (afinidade do balanceador de carga)
- Pub/sub do Redis para mensagens entre instâncias
- Limites de conexão por instância
- Heartbeat/ping para detectar conexões mortas
- Desligamento gracioso (notificar clientes, fechar conexões)SSE. Notificações são do servidor para o cliente. SSE oferece reconexão automática e funciona através da infraestrutura HTTP.
Sim. SSE funciona sobre HTTP/1.1 e HTTP/2. Desative o buffer do proxy no nginx.
Quando você precisa de salas, fallback automático e um adaptador Redis para escalabilidade. Veja Socket.IO.
10k-50k conexões ociosas dependendo da memória. A disseminação ativa reduz isso. Perfis com seus padrões de mensagem.
Não. Use REST HTTP para CRUD. Adicione WebSocket/SSE apenas para requisitos de push em tempo real.
Versões da Stack: Esta página foi escrita para Node.js 24.18.0 (Active LTS), npm 10+, TypeScript 5.6+, Express 5, Fastify 5 e NestJS 11.
Revisado por Chris St. John·Última atualização: 16 de jul. de 2026