From e5834929a868bb15de9bc7b832d3e38c567764c8 Mon Sep 17 00:00:00 2001 From: Evgenii Date: Sun, 29 Jun 2025 14:27:47 +0300 Subject: [PATCH] Sends a heartbeat (ping) to all connected clients to keep connections alive. This method sends ping notifications to all active sessions without expecting a response, which helps prevent connection timeouts. @return A Mono that completes when heartbeat has been sent to all sessions --- .../WebFluxSseServerTransportProvider.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/mcp-spring/mcp-spring-webflux/src/main/java/io/modelcontextprotocol/server/transport/WebFluxSseServerTransportProvider.java b/mcp-spring/mcp-spring-webflux/src/main/java/io/modelcontextprotocol/server/transport/WebFluxSseServerTransportProvider.java index 62264d9aa..134675337 100644 --- a/mcp-spring/mcp-spring-webflux/src/main/java/io/modelcontextprotocol/server/transport/WebFluxSseServerTransportProvider.java +++ b/mcp-spring/mcp-spring-webflux/src/main/java/io/modelcontextprotocol/server/transport/WebFluxSseServerTransportProvider.java @@ -229,6 +229,28 @@ public Mono closeGracefully() { .then(); } + /** + * Sends a heartbeat (ping) to all connected clients to keep connections alive. This + * method sends ping notifications to all active sessions without expecting a + * response, which helps prevent connection timeouts. + * @return A Mono that completes when heartbeat has been sent to all sessions + */ + public Mono sendHeartbeat() { + if (sessions.isEmpty()) { + logger.debug("No active sessions to send heartbeat to"); + return Mono.empty(); + } + + logger.debug("Sending heartbeat to {} active sessions", sessions.size()); + + return Flux.fromIterable(sessions.values()) + .flatMap(session -> session.sendNotification(McpSchema.METHOD_PING, null) + .doOnSuccess(v -> logger.trace("Heartbeat sent successfully to session {}", session.getId())) + .doOnError(e -> logger.warn("Heartbeat failed for session {}: {}", session.getId(), e.getMessage())) + .onErrorComplete()) // Continue with other sessions even if one fails + .then(); + } + /** * Returns the WebFlux router function that defines the transport's HTTP endpoints. * This router function should be integrated into the application's web configuration.