package xyz.mcutils.backend.websocket; import lombok.extern.log4j.Log4j2; import org.jetbrains.annotations.NotNull; import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.handler.TextWebSocketHandler; import xyz.mcutils.backend.Main; import xyz.mcutils.backend.common.Timer; import xyz.mcutils.backend.service.MetricService; import xyz.mcutils.backend.service.metric.metrics.TotalRequestsMetric; import xyz.mcutils.backend.service.metric.metrics.UniquePlayerLookupsMetric; import xyz.mcutils.backend.service.metric.metrics.UniqueServerLookupsMetric; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; @Log4j2(topic = "WebSocket/Metrics") public class MetricsWebSocketHandler extends TextWebSocketHandler { private final long interval = TimeUnit.SECONDS.toMillis(5); public static final List<WebSocketSession> SESSIONS = new ArrayList<>(); private final MetricService metricService; public MetricsWebSocketHandler(MetricService metricService) { this.metricService = metricService; Timer.scheduleRepeating(() -> { for (WebSocketSession session : SESSIONS) { sendMetrics(session); } }, interval, interval); } /** * Sends the metrics to the client. * * @param session the session to send the metrics to */ private void sendMetrics(WebSocketSession session) { try { session.sendMessage(new TextMessage(Main.GSON.toJson(Map.of( "totalRequests", metricService.getMetric(TotalRequestsMetric.class).getValue(), "uniqueServerLookups", metricService.getMetric(UniqueServerLookupsMetric.class).getValue(), "uniquePlayerLookups", metricService.getMetric(UniquePlayerLookupsMetric.class).getValue() )))); } catch (Exception e) { log.error("An error occurred while sending metrics to the client", e); } } @Override public void afterConnectionEstablished(WebSocketSession session) { log.info("WebSocket connection established with session id: {}", session.getId()); sendMetrics(session); SESSIONS.add(session); } @Override public void afterConnectionClosed(WebSocketSession session, @NotNull CloseStatus status) { log.info("WebSocket connection closed with session id: {}", session.getId()); SESSIONS.remove(session); } }