Introducción a WebSocket en Java: de la teoría a aplicaciones en tiempo real
Las aplicaciones web modernas requieren cada vez más un intercambio instantáneo de datos entre el cliente y el servidor. El HTTP tradicional con su modelo de "solicitud-respuesta" no es adecuado para tareas que necesitan una comunicación constante: chats en línea, cotizaciones bursátiles, juegos multijugador o paneles de monitoreo. Aquí es donde entra en juego el protocolo WebSocket, que establece una conexión bidireccional permanente. En este artículo, analizaremos cómo implementar WebSocket en Java, crearemos un servidor y cliente de chat simple, y veremos las mejores prácticas para un entorno de producción.
¿Qué es WebSocket y por qué Java?
WebSocket es un protocolo que funciona sobre TCP y permite intercambiar mensajes en tiempo real sin la sobrecarga de las cabeceras HTTP. Después del handshake (actualización de HTTP a WebSocket), el servidor y el cliente pueden enviarse datos en cualquier momento. Java es una excelente opción para implementar WebSocket gracias a:
- Soporte integrado en Jakarta EE (anteriormente Java EE) a través de JSR 356.
- Alto rendimiento y capacidades de subprocesamiento múltiple.
- Ecosistema de frameworks (Spring, Netty, Tyrus) que simplifican el desarrollo.
A diferencia de polling y SSE (Server-Sent Events), WebSocket proporciona una comunicación bidireccional completa sin latencias.
Arquitectura de una aplicación WebSocket en Java
Una aplicación típica en tiempo real en Java incluye tres componentes:
- Servidor WebSocket — acepta conexiones, gestiona sesiones, procesa mensajes entrantes.
- Cliente WebSocket — navegador (JavaScript) o aplicación Java nativa que inicia la conexión.
- Lógica de negocio — procesamiento de mensajes, broadcast, almacenamiento en BD.
Veamos la implementación del servidor usando anotaciones Jakarta WebSocket y un cliente en JavaScript.
Parte del servidor: anotaciones @ServerEndpoint
Para crear un servidor, basta con añadir la dependencia jakarta.websocket-api (o javax.websocket-api para versiones antiguas). Ejemplo de un servidor echo simple:
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("Nueva conexión: " + session.getId()); }
@OnMessage public void onMessage(String message, Session session) throws IOException { System.out.println("Recibido: " + message); // Enviar de vuelta (echo) session.getBasicRemote().sendText("Echo: " + message); }
@OnClose public void onClose(Session session, CloseReason reason) { System.out.println("Conexión cerrada: " + reason.getReasonPhrase()); }
@OnError public void onError(Session session, Throwable error) { error.printStackTrace(); }}El servidor se despliega en cualquier contenedor Servlet (Tomcat, Jetty, GlassFish). Para Spring Boot, use @ServerEndpoint junto con SpringBootApplication.
Parte del cliente: JavaScript
El cliente del navegador se conecta a través de la API WebSocket estándar:
const socket = new WebSocket("ws://localhost:8080/echo");
socket.onopen = function(event) { console.log("Conexión establecida"); socket.send("¡Hola, servidor!");};
socket.onmessage = function(event) { console.log("Mensaje del servidor: " + event.data);};
socket.onclose = function(event) { console.log("Conexión cerrada");};Tenga en cuenta: la URL comienza con ws:// (o wss:// para conexión segura).
Creación de un chat en tiempo real en Java
Ahora construiremos un chat completo
```