WebSocket¶
Guía de integración con WebSocket (STOMP sobre SockJS).
Endpoint¶
Configuración¶
La configuración está en WebSocketConfig.java:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws")
.setAllowedOrigins("*")
.withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/app");
registry.enableSimpleBroker("/topic", "/queue");
}
}
Detalles¶
- Endpoint STOMP:
/ws - Broker:
/topic(broadcast),/queue(punto a punto) - Prefijo apps:
/app
Uso con JavaScript (SockJS)¶
// Instalar STOMP client
npm install @stomp/stompjs sockjs-client
// Conectar
const sock = new SockJS('http://localhost:8080/ws');
const stompClient = Stomp.over(sock);
stompClient.connect({ headers: { Authorization: 'Bearer ' + token } },
(frame) => {
console.log('Connected: ' + frame);
// Suscribirse a mensajes
stompClient.subscribe('/topic/mensajes', (message) => {
console.log('Mensaje:', message.body);
});
// Enviar mensaje
stompClient.send('/app/chat', {}, JSON.stringify({
receiverId: 123,
mensaje: 'Hola!'
}));
},
(error) => {
console.log('Error:', error);
}
);
Uso con Java (Cliente)¶
@Configuration
public class WebSocketClientConfig {
@Bean
public WebSocketStompClient webSocketStompClient() {
WebSocketClient client = new SockJsClient(Collections.singletonList(
new WebSocketTransport(new StandardWebSocketClient())
));
return new WebSocketStompClient(client);
}
@Bean
public StompSession stompSession(WebSocketStompClient stompClient) {
return stompClient.connect("ws://localhost:8080/ws",
new StompSessionHandlerAdapter() {});
}
}
Eventos WebSocket en Amani¶
1. Mensajes en Tiempo Real¶
Destino: /topic/mensajes
// En el controller
@MessageMapping("/chat")
@SendTo("/topic/mensajes")
public ChatMessageDTO enviarMensaje(ChatMessageDTO message) {
return mensajeService.enviarMensaje(message);
}
2. Notificaciones Push¶
Si el usuario está offline → Firebase Push.
// En FirebaseNotificationService
public void enviarPush(String fcmToken, String titulo, String cuerpo) {
// Envía notificación via FCM
}
Protocolo STOMP¶
Headers Comunes¶
| Header | Valor |
|---|---|
Authorization | Bearer {token_jwt} |
content-type | application/json |
Comandos¶
| Comando | Descripción |
|---|---|
CONNECT | Iniciar conexión |
SUBSCRIBE | Suscribirse a un destino |
SEND | Enviar mensaje |
DISCONNECT | Cerrar conexión |
Seguridad¶
Los endpoints WebSocket requieren autenticación JWT:
El token se envía en el header Authorization:
Troubleshooting¶
Error: "Connection refused"¶
- Verificar WebSocketConfig.java existe
- Verificar
spring-boot-starter-websocketen dependencies
Error: "Not authenticated"¶
- Incluir token JWT en header
Authorization - Verificar token no ha expirado
Error: "No destination mapping"¶
- Verificar
@MessageMappingen el controller - Verificar destino coincide con
@SendTo
Ejemplo Completo¶
// chat.js
class ChatClient {
constructor(token) {
this.token = token;
this.stompClient = null;
}
connect() {
const sock = new SockJS('http://localhost:8080/ws');
this.stompClient = Stomp.over(sock);
this.stompClient.connect(
{ headers: { Authorization: 'Bearer ' + this.token } },
this.onConnected.bind(this),
this.onError.bind(this)
);
}
onConnected(frame) {
console.log('Conectado:', frame);
// Suscribirse
this.stompClient.subscribe('/topic/mensajes', (msg) => {
this.onMessageReceived(JSON.parse(msg.body));
});
}
onMessageReceived(message) {
console.log('Mensaje:', message);
// Renderizar mensaje
}
sendMessage(receiverId, texto) {
this.stompClient.send('/app/chat', {}, JSON.stringify({
receiverId: receiverId,
mensaje: texto,
enviadoEn: new Date().toISOString()
}));
}
disconnect() {
if (this.stompClient) {
this.stompClient.disconnect();
}
}
}