Um WebSocket é uma conexão persistente e bidirecional entre cliente e servidor, que permite a qualquer lado enviar mensagens no instante em que acontecem. O HTTP construiu a web perguntando; os WebSockets a deixaram ao vivo escutando — um upgrade padronizado (RFC 6455) transforma uma request em um canal aberto, e tudo que é tempo real na web — chat, presença, tickers, cursores colaborativos — roda sobre ele.
Principais pontos
| Pergunta | Resposta |
|---|---|
| O que é | Uma conexão persistente e full-duplex — push do servidor, envio do cliente, mesmo cano |
| vs. HTTP | Request-response stateless vs. canal aberto stateful |
| O handshake | GET HTTP + Upgrade → 101 Switching Protocols → frames |
| Regras de produção | Sempre wss://, heartbeats + reconexão com backoff, planeje o fan-out |
| A camada acima | Sincronização em tempo real — consultas e estado sobre o socket, não mensagens cruas |
Como funciona o handshake de upgrade do WebSocket (HTTP 101)
GET /chat HTTP/1.1 ← começa como HTTP comum
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
HTTP/1.1 101 Switching Protocols ← e deixa de ser HTTP aqui
Upgrade: websocket
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
# Daqui em diante: frames mínimos (2–14 bytes de overhead), nas duas direções,
# vs. ~500+ bytes de headers em cada poll HTTP.
A maioria das aplicações não deveria escrever à mão o que vem depois — o idioma de produção é uma camada gerenciada de tempo real em que o socket, os heartbeats e a reconexão são código de outra pessoa:
// JavaScript / Node.js — Back4app JS SDK (Live Query over WebSockets)
// One WebSocket, managed for you: connect, subscribe, reconnect
const query = new Parse.Query('Message');
query.equalTo('room', 'general');
const subscription = await query.subscribe(); // wss:// under the hood
subscription.on('create', (msg) => appendToChat(msg));
subscription.on('open', () => setStatus('live'));
// Later: subscription.unsubscribe(); // Flutter / Dart — Back4app Flutter SDK (Live Query over WebSockets)
// One WebSocket, managed for you: connect, subscribe, reconnect
final liveQuery = LiveQuery();
final query = QueryBuilder<ParseObject>(ParseObject('Message'))
..whereEqualTo('room', 'general');
final sub = await liveQuery.client.subscribe(query); // wss:// under the hood
sub.on(LiveQueryEvent.create, (msg) => appendToChat(msg)); // iOS / Swift — Back4app Swift SDK (Live Query over WebSockets)
// One WebSocket, managed for you: connect, subscribe, reconnect
let query = Message.query("room" == "general")
let subscription = query.subscribeCallback // wss:// under the hood
subscription?.handleEvent { _, event in
if case .created(let msg) = event { appendToChat(msg) }
} // Android / Kotlin — Back4app Android SDK (Live Query over WebSockets)
// One WebSocket, managed for you: connect, subscribe, reconnect
val client = ParseLiveQueryClient.Factory.getClient()
val query = ParseQuery.getQuery<ParseObject>("Message")
query.whereEqualTo("room", "general")
val handling = client.subscribe(query) // wss:// under the hood
handling.handleEvent(SubscriptionHandling.Event.CREATE) { _, msg ->
appendToChat(msg)
} WebSockets vs. todo o resto que move dados
| Transporte | Direção | Como funciona | Melhor para |
|---|---|---|---|
| Polling | Cliente pergunta repetidamente | Uma request completa por verificação | Só como fallback legado |
| Long polling | Cliente pergunta, servidor segura | Uma request pendente por mensagem | Fallback de compatibilidade |
| SSE | Só servidor → cliente | HTTP em streaming, reconexão automática | Feeds, tickers, notificações |
| WebSocket | Nas duas direções | TCP persistente após upgrade | Chat, jogos, colaboração, sincronização |
| WebRTC | Peer ↔ peer | Canais UDP de mídia/dados | Chamadas, vídeo — sinalizados via WebSockets |
Rodando sockets em produção
Quatro conceitos carregam o peso operacional. Afinidade de sessão: conexões são stateful, então os load balancers precisam manter cada cliente preso ao seu nó de servidor. Fan-out: transmitir uma mensagem para dez mil assinantes espalhados por muitos nós exige um backplane de pub/sub entre servidores — a mensagem viaja de servidor a servidor antes de viajar de servidor a cliente. Backpressure: um celular lento numa rede ruim não pode acumular mensagens sem limite na memória do seu servidor; descarte, agrupe ou desconecte. Liveness: frames ping/pong mais heartbeats de aplicação detectam conexões meio-mortas, e os clientes reconectam com backoff exponencial e jitter, e então reinscrevem seu estado — o passo que implementações ingênuas esquecem. Nada disso é exótico; tudo isso é o motivo de “a gente só abre um socket” virar uma decisão de plataforma.
De mensagens a sincronização: a camada acima
WebSockets crus movem bytes; aplicações querem estado. O degrau acima é a sincronização em tempo real: em vez de inventar tipos de mensagem e contabilidade no cliente, você se inscreve em dados — uma consulta, um documento, um canal — e a camada entrega eventos de mudança precisos, cuida do reconectar-e-atualizar e aplica permissões server-side por assinante. Esse é o modelo de live queries: WebSockets como transporte, um motor de consultas como cérebro. Se o seu código WebSocket está acumulando switch statements sobre tipos de mensagem, você está reconstruindo essa camada à mão.
Casos de uso comuns
- Chat e mensagens — o caso canônico: os dois lados falam, instantaneamente.
- Presença — quem está online, quem está digitando: mensagens minúsculas, alta frequência, nas duas direções.
- Edição colaborativa — documentos e quadros compartilhados, em que posições de cursor e edições fluem continuamente.
- Dashboards ao vivo e tickers — push de números que mudam; SSE também serve quando é só de ida.
- Multiplayer e localização — estado de jogo e marcadores se movendo no mapa, em que latência é o produto.
Você precisa de um socket? Matriz de decisão
| Escolha WebSockets quando… | HTTP puro é o certo quando… |
|---|---|
| Usuários observam dados que mudam agora | Os dados mudam raramente ou sob demanda |
| Os dois lados iniciam mensagens | Só o cliente pergunta, sempre |
| A latência é visível ao usuário (chat, jogos) | Um poll de 30 segundos honestamente resolveria |
| Muitas mensagens pequenas fluem o tempo todo | As respostas são grandes e cacheáveis |
| Você vai rodar (ou alugar) o fan-out | Ninguém é dono da operação dos sockets |
E o caminho do meio que a matriz esconde: casos só de servidor para cliente (feeds, notificações) cabem em SSE com bem menos maquinário — a comparação completa de transportes tem seu próprio verbete no registro deste glossário.
Limitações e trade-offs
- Statefulness é o preço do push. Cada conexão aberta é memória de servidor e uma restrição de balanceamento; a ausência de estado do HTTP carregava mais peso do que parecia.
- Redes odeiam conexões longas. Proxies, rádios de celular e laptops fechando a tampa cortam sockets o tempo todo — lógica de reconexão não é caso de borda, é o loop principal.
- A segurança se muda para a conexão. Autentique no connect, valide cada mensagem, aplique autorização por subscription — e sempre wss.
- Cache não existe aqui. Tudo que é enviado por push é computado e entregue por cliente; o CDN não pode ajudar.
- Sincronização feita à mão é uma armadilha. A distância entre “abri um socket” e “sincronização de estado correta, com reconexão e permissões” é onde mora a engenharia de verdade — que é exatamente a camada que vale alugar.
WebSockets no Back4app
O Back4app é uma plataforma open-source de Backend as a Service (BaaS) que combina banco de dados gerenciado, APIs REST e GraphQL geradas automaticamente, autenticação, armazenamento de arquivos e funções serverless com Cloud Code. Sua camada de tempo real é o Live Query: o transporte WebSocket, os heartbeats, a reconexão e o fan-out multi-nó rodam como infraestrutura gerenciada (com o protocolo aberto LiveQuery por baixo), enquanto o seu código se inscreve em consultas e recebe eventos de mudança tipados — com ACLs aplicadas por assinante, para que o tempo real nunca passe por cima do modelo de permissões. As abas de código acima são toda a história do lado do cliente.
Perguntas frequentes
O que é um WebSocket em termos simples?
Uma ligação telefônica em vez de uma troca de cartas. HTTP é request-response — o cliente pergunta, o servidor responde, a linha fecha. Um WebSocket abre uma conexão persistente pela qual os dois lados enviam mensagens a qualquer momento, com poucos bytes de framing por mensagem em vez de headers completos. É o transporte padrão (RFC 6455) para chat, dados ao vivo e colaboração.
Qual a diferença entre WebSocket e HTTP?
Direção e tempo de vida. HTTP é stateless e iniciado pelo cliente: cada troca é uma request nova com headers completos, e o servidor nunca fala primeiro. Um WebSocket começa como uma request HTTP, faz o upgrade e vira um canal stateful e full-duplex em que o servidor faz push sem ser perguntado — que é o ponto inteiro para qualquer coisa que muda enquanto o usuário olha.
Como funciona o handshake do WebSocket?
Começa como HTTP educado: o cliente envia um GET com os headers Upgrade e Connection mais um Sec-WebSocket-Key aleatório; o servidor responde 101 Switching Protocols com um hash de aceite derivado dessa chave. A partir daí, a conexão TCP para de falar HTTP e passa a carregar frames WebSocket leves nas duas direções, até que um dos lados a feche.
Qual a diferença entre ws:// e wss://?
A mesma que existe entre http e https: wss roda a conexão sobre TLS. Tráfego de produção é sempre wss — por privacidade e, na prática, porque conexões criptografadas atravessam proxies e middleboxes corporativos que corrompem upgrades em texto puro. Não existe razão legítima para colocar ws em produção.
Qual a diferença entre WebSockets e Server-Sent Events?
Direção. SSE é unidirecional — o servidor transmite ao cliente sobre HTTP puro, com reconexão automática embutida — ideal para feeds, tickers e notificações. WebSockets são bidirecionais, para qualquer caso em que o cliente também fala: chat, jogos, edição colaborativa. SSE é mais simples onde basta; WebSockets são a ferramenta geral.
Como funcionam reconexões e heartbeats?
O protocolo inclui frames de controle ping/pong para cada lado verificar se o outro está vivo; as aplicações somam heartbeats por cima para detectar conexões meio-mortas, reconectam com backoff exponencial mais jitter e reinscrevem seu estado. Camadas gerenciadas de tempo real cuidam desse ciclo por você — código WebSocket feito à mão que pula essa parte funciona até o dia em que a rede se comporta como rede.
WebSockets escalam?
Sim, com mecânica diferente da do HTTP: conexões são stateful, então load balancers precisam de afinidade de sessão; broadcast para muitos clientes exige um backplane de pub/sub para que cada nó faça fan-out das mensagens; e consumidores lentos pedem tratamento de backpressure para que um cliente travado não infle a memória. São problemas resolvidos — em infraestrutura que você constrói ou aluga.
Quando NÃO usar WebSockets?
Quando request-response já resolve: buscar recursos cacheáveis, CRUD padrão, atualizações raras. Uma conexão persistente compra push instantâneo e paga por isso em statefulness — inútil para dados que mudam raramente. A regra prática: se um polling a cada 30 segundos honestamente bastaria, dispense o socket.