Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Keep-Alive for GraphQL Subscriptions over SSE with Spring WebFlux/WebMvc #1048

Open
jma-9code opened this issue Aug 20, 2024 · 0 comments
Labels
in: web Issues related to web handling type: enhancement A general enhancement
Milestone

Comments

@jma-9code
Copy link

Description:
Currently, when using GraphQL Subscriptions over Server-Sent Events (SSE) with Spring WebFlux or Spring WebMvc, there is no built-in mechanism to support keep-alive. This is a significant issue because, without a keep-alive mechanism, intermediary tools such as load balancers or proxies might close the connection due to inactivity.

For WebSocket, a keep-alive mechanism is available, which helps to maintain the connection alive over time. A similar solution is needed for SSE to ensure stable and persistent connections.

Workaround:
At present, a common workaround involves sending a dummy business object at regular intervals to keep the connection alive. Here’s an example:

@SubscriptionMapping(value = "notifications")
public Flux<UserNotification> notifications() {
    var data = getLoggedUser()
        .flatMapMany(user -> userNotifService.streamNotificationsByUser(user.getId()));
    var keepAlive = Flux.interval(java.time.Duration.ofSeconds(30))
        .map(i -> UserNotification.builder().id("-1").build());
    return Flux.merge(data, keepAlive);
}

In this example, a dummy UserNotification object with a fake ID is sent every 30 seconds to prevent the connection from being closed. While this approach works, it is far from ideal and can add unnecessary complexity and overhead to the application.

Proposed Solution:
Introduce a configuration property similar to the one used for WebSocket, such as:

spring.graphql.sse.keepalive: Duration

Instead of sending dummy business objects, this feature could automatically send an SSE event with an empty data payload and a "ping" event type at the specified interval. For example:

event: "ping"
data: \n\n

This configuration would allow developers to specify a keep-alive interval for SSE connections, ensuring that the connection remains open and active, thus preventing premature disconnection by intermediary tools. The principal implementation support this ping inside his parser => https://github.com/enisdenjo/graphql-sse/blob/master/src/parser.ts

Importance:
Supporting a keep-alive mechanism for SSE is critical for production environments where long-lived connections are necessary for real-time data streams. Without this feature, GraphQL Subscriptions over SSE are less reliable, particularly in environments where network infrastructure may close idle connections.

Thank you for considering this feature request.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Aug 20, 2024
@bclozel bclozel added type: enhancement A general enhancement in: web Issues related to web handling and removed status: waiting-for-triage An issue we've not yet triaged labels Aug 20, 2024
@bclozel bclozel modified the milestones: 1.3.3, 1.4.x Aug 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues related to web handling type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

3 participants