I'm trying to implement a websocket on using Spring Boot (1.5.13).
The messaging works fine but after about 30 minutes the connection is terminated by the server (Reason 1008 - "This connection was established under an authenticated HTTP session that has ended"). I've tried to set different timeouts but doesn't seem to have any effect.
@Service
@RequiredArgsConstructor
@Slf4j
public class OCPPSocketHandler extends TextWebSocketHandler {
@Override
public void handleTextMessage(WebSocketSession webSocketSession, TextMessage textMessage)
throws IOException {
...
}
}
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
public static final String ENDPOINT = "/pp/v2.0";
@Autowired
private CustomSocketHandler socketHandler;
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(
new CustomExceptionWebSocketHandlerDecorator(socketHandler), ENDPOINT
)
.setAllowedOrigins("*");
}
}
application.properties:
#6h as milliseconds
server.connection-timeout=3600000
server.servlet.session.timeout=6h
A TextMessage (WebSocket) is sent every 30 minutes to keep the connection alive.
I've seen this question about session timeouts but I can't see a solution there
I found my WebSocket closed after 30 minutes too.
The root reason is the http session will close after 30 minutes by default in SpringBoot.
In SpringBoot config property server.servlet.session.timeout
will change the default behavior, but there might have some limit.
Besides, WebSocket connections have pingpong messages to keep alive, so the connection should never be closed, until the pingpong stops.
After some tracing, I found a way to solve this problem:
io.undertow.server.session.InMemorySessionManager.SessionImpl
in my case.io.undertow.server.session.InMemorySessionManager.SessionImpl#setMaxInactiveInterval
will reset the timer.javax.servlet.http.HttpSession#setMaxInactiveInterval
.setMaxInactiveInterval
is called before each timeout, the connection will never be closed.Here is my implementation:
HandshakeRequest
into the javax.websocket.EndpointConfig#getUserProperties
in the Configurator javax.websocket.server.ServerEndpointConfig.Configurator#modifyHandshake
onMessage
method, fetch the HandshakeRequest
from javax.websocket.Session#getUserProperties
, thenHttpSession httpSession = (HttpSession) handshakeRequest.getHttpSession();
httpSession.setMaxInactiveInterval((int) (session.getMaxIdleTimeout() / 1000));
That's all, hope it helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With