WebSockets em Java: de chats a gráficos de bolsa em tempo real

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

WebSockets em Java: quando o HTTP já não é suficiente

\n\n

Imagine uma bolsa de valores online. Você olha para o gráfico do preço do Bitcoin. A cada segundo, os números mudam. Ou um jogo multiplayer, onde você move o personagem e centenas de outros jogadores veem isso instantaneamente. Ou simplesmente um chat corporativo, onde as mensagens chegam sem precisar apertar F5.

\n\n

Como isso funciona nos bastidores? Antigamente, os desenvolvedores se viravam: polling (o cliente pergunta ao servidor a cada segundo "e aí, tem novidades?"), long polling (o servidor mantém a conexão até que haja uma novidade), Server-Sent Events (fluxo unidirecional). Tudo isso são gambiarras. O protocolo HTTP foi originalmente criado como requisição-resposta. Ele não sabe "empurrar" dados sozinho.

\n\n

É aí que entram os WebSockets. É um protocolo que estabelece uma conexão uma vez — e a mantém aberta. O servidor pode enviar dados ao cliente a qualquer momento, e vice-versa. Comunicação bidirecional em tempo real, sem a sobrecarga dos cabeçalhos HTTP.

\n\n

Neste artigo, vamos abordar WebSockets em Java do início ao fim. Vamos escrever um chat completo, analisar as armadilhas e comparar bibliotecas populares. Se você é um desenvolvedor Java e quer criar aplicações em tempo real com Java, está no lugar certo.

\n\n

Como funciona o WebSocket? Breve introdução

\n\n

WebSocket não é mágica, é apenas um protocolo sobre TCP. Ele começa como uma requisição HTTP comum (handshake) e depois é "atualizado" para um canal bidirecional permanente.

\n\n

Etapa 1: Handshake (Aperto de mão)

\n

O cliente envia uma requisição HTTP GET comum com o cabeçalho Upgrade: websocket. O servidor responde com o código 101 Switching Protocols. Pronto. A partir deste momento, os dados não trafegam mais como pacotes HTTP, mas como frames WebSocket.

\n\n

Etapa 2: Frames de dados

\n

Os dados são transmitidos em pequenos pacotes (frames). Um frame pode ser de texto (string comum) ou binário (imagem, áudio). As bibliotecas Java escondem essa complexidade — você trabalha simplesmente com strings ou bytes.

\n\n

Etapa 3: Fechamento

\n

Qualquer lado pode iniciar o fechamento da conexão, enviando um frame especial de Close.

\n\n

Parece simples? E é. Mas o diabo está nos detalhes: timeouts, reconexões, escalabilidade. Mas falaremos disso mais tarde.

\n\n

Bibliotecas para WebSockets em Java

\n\n

No ecossistema Java, existem três abordagens principais:

\n\n
    \n
  • Jakarta WebSocket (JSR 356) — padrão Java EE / Jakarta EE. Funciona em qualquer servidor compatível (Tomcat, Jetty, GlassFish). Muitas anotações, pouco código.
  • \n
  • Spring WebSocket — uma camada sobre o padrão no ecossistema Spring. Oferece integração com Security, STOMP (protocolo sobre WebSocket para inscrição em tópicos) e templates convenientes.
  • \n
  • Netty / Vert.x / Undertow — frameworks assíncronos de baixo nível. Máximo desempenho, mas mais código.
  • \n
\n\n

Para 90% dos casos, Jakarta ou Spring são suficientes. Vamos analisar ambas as opções com exemplos reais.

\n\n

Exemplo 1: Chat simples com Jakarta WebSocket (sem Spring)

\n\n

Suponha que temos um bom e velho Tomcat 10+ (Jakarta EE). Precisamos de um endpoint no servidor e um cliente (HTML+JS).

\n\n

Servidor: classe endpoint

\n
import jakarta.websocket.*;\nimport jakarta.websocket.server.ServerEndpoint;\nimport java.io.IOException;\nimport java.util.Set;\nimport java.util.concurrent.CopyOnWriteArraySet;\n\n@ServerEndpoint("/chat")\npublic class ChatEndpoint {\n\n    // Armazena todas as sessões ativas (conjunto thread-safe)\n    private static final Set<Session> sessions = new CopyOnWriteArraySet<>();\n\n    @OnOpen\n    public void onOpen(Session session) {\n        sessions.add(session);\n        broadcast("Usuário conectou. Total no chat: " + sessions.size());\n    }\n\n    @OnMessage\n    public void onMessage(String message, Session session) {\n        // Pode-se adicionar lógica: enviar apenas                

Blogs

Book Recommendations