Add check for unused WebSocket sessions
Sessions connected to a STOMP endpoint are expected to receive some
client messages. Having received none after successfully connecting
could be an indication of proxy or network issue. This change adds
periodic checks to see if we have not received any messages on a
session which is an indication the session isn't going anywhere
most likely due to a proxy issue (or unreliable network) and close
those sessions.
This is a backport for commit:
a3fa9c9797
Issue: SPR-11884
This commit is contained in:
@@ -17,16 +17,24 @@
|
||||
package org.springframework.web.socket.messaging;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.SubscribableChannel;
|
||||
import org.springframework.web.socket.CloseStatus;
|
||||
import org.springframework.web.socket.TextMessage;
|
||||
import org.springframework.web.socket.handler.ConcurrentWebSocketSessionDecorator;
|
||||
import org.springframework.web.socket.handler.TestWebSocketSession;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
@@ -140,4 +148,32 @@ public class SubProtocolWebSocketHandlerTests {
|
||||
this.webSocketHandler.afterConnectionEstablished(session);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkSession() throws Exception {
|
||||
TestWebSocketSession session1 = new TestWebSocketSession("id1");
|
||||
TestWebSocketSession session2 = new TestWebSocketSession("id2");
|
||||
session1.setAcceptedProtocol("v12.stomp");
|
||||
session2.setAcceptedProtocol("v12.stomp");
|
||||
|
||||
this.webSocketHandler.setProtocolHandlers(Arrays.asList(this.stompHandler));
|
||||
this.webSocketHandler.afterConnectionEstablished(session1);
|
||||
this.webSocketHandler.afterConnectionEstablished(session2);
|
||||
session1.setOpen(true);
|
||||
session2.setOpen(true);
|
||||
|
||||
long sixtyOneSecondsAgo = System.currentTimeMillis() - 61 * 1000;
|
||||
new DirectFieldAccessor(this.webSocketHandler).setPropertyValue("lastSessionCheckTime", sixtyOneSecondsAgo);
|
||||
Map<String, ?> sessions = (Map<String, ?>) new DirectFieldAccessor(this.webSocketHandler).getPropertyValue("sessions");
|
||||
new DirectFieldAccessor(sessions.get("id1")).setPropertyValue("createTime", sixtyOneSecondsAgo);
|
||||
new DirectFieldAccessor(sessions.get("id2")).setPropertyValue("createTime", sixtyOneSecondsAgo);
|
||||
|
||||
this.webSocketHandler.start();
|
||||
this.webSocketHandler.handleMessage(session1, new TextMessage("foo"));
|
||||
|
||||
assertTrue(session1.isOpen());
|
||||
assertFalse(session2.isOpen());
|
||||
assertNull(session1.getCloseStatus());
|
||||
assertEquals(CloseStatus.SESSION_NOT_RELIABLE, session2.getCloseStatus());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user