diff --git a/src/main/java/com/example/fercoganbackend/component/ContadorWebSocketHandler.java b/src/main/java/com/example/fercoganbackend/component/ContadorWebSocketHandler.java index 7d10f16..9942050 100644 --- a/src/main/java/com/example/fercoganbackend/component/ContadorWebSocketHandler.java +++ b/src/main/java/com/example/fercoganbackend/component/ContadorWebSocketHandler.java @@ -1,34 +1,119 @@ package com.example.fercoganbackend.component; -// ContadorWebSocketHandler.java +import com.example.fercoganbackend.service.ContadorService; import org.springframework.stereotype.Component; import org.springframework.web.socket.*; import org.springframework.web.socket.handler.TextWebSocketHandler; - -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; @Component public class ContadorWebSocketHandler extends TextWebSocketHandler { - private final List sessions = new CopyOnWriteArrayList<>(); + + private final Map> sesionesPorLote = new ConcurrentHashMap<>(); + private final ContadorService contadorService; + + public ContadorWebSocketHandler(ContadorService contadorService) { + this.contadorService = contadorService; + } @Override - public void afterConnectionEstablished(WebSocketSession session) { - sessions.add(session); + public void afterConnectionEstablished(WebSocketSession session) throws Exception { + String roomKey = extraerRoomKey(session); + + System.out.println("=== NUEVA CONEXIÓN WEBSOCKET ==="); + System.out.println("Session ID: " + session.getId()); + System.out.println("URI: " + session.getUri()); + System.out.println("Room Key: " + roomKey); + System.out.println("Sesiones activas en " + roomKey + ": " + + (sesionesPorLote.get(roomKey) != null ? sesionesPorLote.get(roomKey).size() : 0)); + + // Agregar sesión a la sala correspondiente + sesionesPorLote.computeIfAbsent(roomKey, k -> new CopyOnWriteArraySet<>()).add(session); + + // Enviar valor actual del contador para este lote + int valorActual = contadorService.getContador(roomKey); + session.sendMessage(new TextMessage(String.valueOf(valorActual))); + + System.out.println("Valor inicial enviado: " + valorActual); + System.out.println("=== CONEXIÓN ESTABLECIDA ==="); } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) { - sessions.remove(session); - } - - public void broadcast(String message) { - for (WebSocketSession session : sessions) { - try { - session.sendMessage(new TextMessage(message)); - } catch (Exception e) { - e.printStackTrace(); + String roomKey = extraerRoomKey(session); + Set sesiones = sesionesPorLote.get(roomKey); + if (sesiones != null) { + sesiones.remove(session); + if (sesiones.isEmpty()) { + sesionesPorLote.remove(roomKey); } } + System.out.println("Conexión cerrada para: " + roomKey + " - " + status); } -} + + @Override + public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { + String roomKey = extraerRoomKey(session); + String payload = message.getPayload(); + + System.out.println("Mensaje recibido de " + roomKey + ": " + payload); + + if ("incrementar".equals(payload)) { + int nuevoValor = contadorService.incrementar(roomKey); + System.out.println("Incrementando " + roomKey + " a: " + nuevoValor); + broadcastToRoom(roomKey, String.valueOf(nuevoValor)); + } + } + + // Broadcast a una sala específica + public void broadcastToRoom(String remate, String lote, String message) { + String roomKey = generarRoomKey(remate, lote); + System.out.println("Broadcast a room: " + roomKey + " - Mensaje: " + message); + broadcastToRoom(roomKey, message); + } + + private void broadcastToRoom(String roomKey, String message) { + Set sesiones = sesionesPorLote.get(roomKey); + System.out.println("Buscando sesiones para: " + roomKey); + System.out.println("Sesiones encontradas: " + (sesiones != null ? sesiones.size() : 0)); + + if (sesiones != null) { + for (WebSocketSession session : sesiones) { + try { + if (session.isOpen()) { + System.out.println("Enviando a session: " + session.getId()); + session.sendMessage(new TextMessage(message)); + } else { + System.out.println("Session cerrada: " + session.getId()); + } + } catch (IOException e) { + System.err.println("Error enviando mensaje a " + session.getId() + ": " + e.getMessage()); + } + } + } else { + System.out.println("No hay sesiones activas para: " + roomKey); + } + } + + private String extraerRoomKey(WebSocketSession session) { + String path = session.getUri().getPath(); + String[] segments = path.split("/"); + + // Para /ws/remate1/lote1 los segmentos son: ["", "ws", "remate1", "lote1"] + if (segments.length >= 4) { + String remate = segments[2]; // índice 2 = remate1 + String lote = segments[3]; // índice 3 = lote1 + return generarRoomKey(remate, lote); + } + + return "default-default"; + } + + private String generarRoomKey(String remate, String lote) { + return remate + "-" + lote; + } +} \ No newline at end of file diff --git a/src/main/java/com/example/fercoganbackend/configuration/WebSocketConfig.java b/src/main/java/com/example/fercoganbackend/configuration/WebSocketConfig.java index 1f7997b..b097d71 100644 --- a/src/main/java/com/example/fercoganbackend/configuration/WebSocketConfig.java +++ b/src/main/java/com/example/fercoganbackend/configuration/WebSocketConfig.java @@ -1,21 +1,24 @@ package com.example.fercoganbackend.configuration; -// WebSocketConfig.java import com.example.fercoganbackend.component.ContadorWebSocketHandler; import org.springframework.context.annotation.Configuration; -import org.springframework.web.socket.config.annotation.*; +import org.springframework.web.socket.config.annotation.EnableWebSocket; +import org.springframework.web.socket.config.annotation.WebSocketConfigurer; +import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { - private final ContadorWebSocketHandler handler; - public WebSocketConfig(ContadorWebSocketHandler handler) { - this.handler = handler; + private final ContadorWebSocketHandler webSocketHandler; + + public WebSocketConfig(ContadorWebSocketHandler webSocketHandler) { + this.webSocketHandler = webSocketHandler; } @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { - registry.addHandler(handler, "/ws/contador").setAllowedOrigins("*"); + registry.addHandler(webSocketHandler, "/ws/{remate}/{lote}") + .setAllowedOrigins("*"); } -} +} \ No newline at end of file diff --git a/src/main/java/com/example/fercoganbackend/controller/ContadorController.java b/src/main/java/com/example/fercoganbackend/controller/ContadorController.java index 1c7db7d..9b8d4d1 100644 --- a/src/main/java/com/example/fercoganbackend/controller/ContadorController.java +++ b/src/main/java/com/example/fercoganbackend/controller/ContadorController.java @@ -1,6 +1,5 @@ package com.example.fercoganbackend.controller; -// ContadorController.java (REST API) import com.example.fercoganbackend.component.ContadorWebSocketHandler; import com.example.fercoganbackend.service.ContadorService; import org.springframework.web.bind.annotation.*; @@ -11,20 +10,38 @@ public class ContadorController { private final ContadorService contadorService; private final ContadorWebSocketHandler webSocketHandler; - public ContadorController(ContadorService contadorService, ContadorWebSocketHandler webSocketHandler) { + public ContadorController(ContadorService contadorService, + ContadorWebSocketHandler webSocketHandler) { this.contadorService = contadorService; this.webSocketHandler = webSocketHandler; } - @PostMapping("/incrementar") - public int incrementar() { - int nuevoValor = contadorService.incrementar(); - webSocketHandler.broadcast(String.valueOf(nuevoValor)); + @PostMapping("/incrementar/{remate}/{lote}") + public int incrementar(@PathVariable String remate, @PathVariable String lote) { + String roomKey = remate + "-" + lote; + int nuevoValor = contadorService.incrementar(roomKey); + + System.out.println("=== INCREMENTAR VIA REST ==="); + System.out.println("Remate: " + remate + ", Lote: " + lote); + System.out.println("Room Key: " + roomKey); + System.out.println("Nuevo valor: " + nuevoValor); + + webSocketHandler.broadcastToRoom(remate, lote, String.valueOf(nuevoValor)); return nuevoValor; } - @GetMapping - public int getContador() { - return contadorService.getContador(); + @GetMapping("/{remate}/{lote}") + public int getContador(@PathVariable String remate, @PathVariable String lote) { + return contadorService.getContador(remate + "-" + lote); } -} + + @PostMapping("/reset/{remate}/{lote}") + public int resetContador(@PathVariable String remate, @PathVariable String lote, + @RequestParam(defaultValue = "200") int valorInicial) { + String roomKey = remate + "-" + lote; + contadorService.setContador(roomKey, valorInicial); + int valor = contadorService.getContador(roomKey); + webSocketHandler.broadcastToRoom(remate, lote, String.valueOf(valor)); + return valor; + } +} \ No newline at end of file diff --git a/src/main/java/com/example/fercoganbackend/service/ContadorService.java b/src/main/java/com/example/fercoganbackend/service/ContadorService.java index 4687752..a312d7c 100644 --- a/src/main/java/com/example/fercoganbackend/service/ContadorService.java +++ b/src/main/java/com/example/fercoganbackend/service/ContadorService.java @@ -1,33 +1,49 @@ package com.example.fercoganbackend.service; -// ContadorService.java import org.springframework.stereotype.Service; import java.util.concurrent.atomic.AtomicInteger; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; @Service public class ContadorService { - private final AtomicInteger contador = new AtomicInteger(200); - private boolean sw = true; + private final Map contadoresPorLote = new ConcurrentHashMap<>(); + private final Map switchesPorLote = new ConcurrentHashMap<>(); + + public int incrementar(String roomKey) { + AtomicInteger contador = contadoresPorLote.computeIfAbsent(roomKey, + k -> new AtomicInteger(200)); + boolean sw = switchesPorLote.computeIfAbsent(roomKey, k -> true); - public int incrementar() { int valorActual = contador.get(); - int incremento; - if (valorActual < 300) { - incremento = sw ? 20 : 30; - sw = !sw; // alterna el booleano - } else if (valorActual < 1000) { - incremento = 50; - } else if (valorActual < 2000) { - incremento = 100; - } else { - incremento = 500; - } + int incremento = calcularIncremento(valorActual, sw); + + // Alternar el switch para este lote + switchesPorLote.put(roomKey, !sw); + return contador.addAndGet(incremento); } - - public int getContador() { - return contador.get(); + public int getContador(String roomKey) { + AtomicInteger contador = contadoresPorLote.get(roomKey); + return contador != null ? contador.get() : 200; // Valor por defecto } -} + public void setContador(String roomKey, int valor) { + AtomicInteger contador = contadoresPorLote.computeIfAbsent(roomKey, + k -> new AtomicInteger(valor)); + contador.set(valor); + } + + private int calcularIncremento(int valorActual, boolean sw) { + if (valorActual < 300) { + return sw ? 20 : 30; + } else if (valorActual < 1000) { + return 50; + } else if (valorActual < 2000) { + return 100; + } else { + return 500; + } + } +} \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 03fcd84..1b1d6d5 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,5 +1,5 @@ spring.application.name=fercoganbackend -spring.profiles.active=prod +spring.profiles.active=dev spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.jpa.hibernate.ddl-auto=update