Introdução ao WebSocket em Java: da teoria às aplicações em tempo real
As aplicações web modernas exigem cada vez mais a troca instantânea de dados entre cliente e servidor. O HTTP tradicional, com seu modelo de "requisição-resposta", não é adequado para tarefas que necessitam de comunicação constante: chats online, cotações de bolsa, jogos multiplayer ou painéis de monitoramento. É aqui que o protocolo WebSocket entra em ação, estabelecendo uma conexão bidirecional permanente. Neste artigo, vamos entender como implementar WebSocket em Java, criar um simples servidor e cliente de chat, além de explorar as melhores práticas para um ambiente de produção.
O que é WebSocket e por que Java?
WebSocket é um protocolo que opera sobre TCP, permitindo a troca de mensagens em tempo real sem a sobrecarga dos cabeçalhos HTTP. Após o handshake (upgrade de HTTP para WebSocket), o servidor e o cliente podem enviar dados um ao outro a qualquer momento. Java é uma excelente escolha para implementar WebSocket devido a:
- Suporte nativo no Jakarta EE (anteriormente Java EE) através do JSR 356.
- Alta performance e capacidade de multithreading.
- Ecossistema de frameworks (Spring, Netty, Tyrus) que simplificam o desenvolvimento.
Diferentemente de polling e SSE (Server-Sent Events), o WebSocket oferece comunicação bidirecional completa sem latências.
Arquitetura de uma aplicação WebSocket em Java
Uma aplicação típica em tempo real em Java inclui três componentes:
- Servidor WebSocket — aceita conexões, gerencia sessões e processa mensagens recebidas.
- Cliente WebSocket — navegador (JavaScript) ou aplicação Java nativa que inicia a conexão.
- Lógica de negócio — processamento de mensagens, broadcast, persistência em banco de dados.
Vamos examinar a implementação do servidor usando anotações do Jakarta WebSocket e um cliente em JavaScript.
Parte do servidor: anotações @ServerEndpoint
Para criar o servidor, basta adicionar a dependência jakarta.websocket-api (ou javax.websocket-api para versões antigas). Exemplo de um servidor echo simples:
import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import java.io.IOException;
@ServerEndpoint("/echo")
public class EchoEndpoint {
@OnOpen
public void onOpen(Session session) {
System.out.println("Nova conexão: " + session.getId());
}
@OnMessage
public void onMessage(String message, Session session) throws IOException {
System.out.println("Recebido: " + message);
// Envia de volta (echo)
session.getBasicRemote().sendText("Echo: " + message);
}
@OnClose
public void onClose(Session session, CloseReason reason) {
System.out.println("Conexão fechada: " + reason.getReasonPhrase());
}
@OnError
public void onError(Session session, Throwable error) {
error.printStackTrace();
}
}
O servidor é implantado em qualquer contêiner Servlet (Tomcat, Jetty, GlassFish). Para Spring Boot, use @ServerEndpoint junto com SpringBootApplication.
Parte do cliente: JavaScript
O cliente no navegador se conecta através da API WebSocket padrão:
const socket = new WebSocket("ws://localhost:8080/echo");
socket.onopen = function(event) {
console.log("Conexão estabelecida");
socket.send("Olá, servidor!");
};
socket.onmessage = function(event) {
console.log("Mensagem do servidor: " + event.data);
};
socket.onclose = function(event) {
console.log("Conexão fechada");
};
Observe que a URL começa com ws:// (ou wss:// para conexão segura).
Criando um chat em tempo real com Java
Agora vamos construir um chat completo
```