Wie kann Sie schnell schließen nonresponsive websocket in Java Spring Tomcat?
Habe ich ein real-time-Anwendung mit clients über websockets an die Verbindung mit dem Spring-Framework-server, die ausgeführt wird Frühling Starten Tomcat. Ich will, dass die server schnell (innerhalb 5 Sekunden) erkennen, wenn ein client reagiert nicht mehr wegen zu einem Netzwerk trennen oder andere Problem und schließen der websocket.
Habe ich versucht
-
Einstellung der max session idle timeout wie in der Dokumentation beschrieben, wie Sie in "Konfigurieren der WebSocket-Motor"
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html@Bean public WebSocketHandler clientHandler() { return new PerConnectionWebSocketHandler(ClientHandler.class); } @Bean public ServletServerContainerFactoryBean createWebSocketContainer() { ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean(); container.setMaxSessionIdleTimeout(5000); container.setAsyncSendTimeout(5000); return container; }
Ich bin nicht sicher, ob dies korrekt umgesetzt, da sehe ich nicht den Zusammenhang zwischen der ServletServerContainerFactoryBean und meine generation ClientHandlers.
-
Senden von ping-Nachrichten vom server alle 2,5 Sekunden. Nachdem ich manuell trennen Sie den client, indem man das Netzwerk-Verbindung, der server glücklich werden pings für weitere 30 Sekunden, bis ein transport-Fehler angezeigt.
-
1 und 2 gleichzeitig
-
1 und 2 und Einstellung
server.session-timeout = 5
in der Anwendung.Eigenschaften
Meine Methode für das testen dieser ist:
- Eine websocket-Verbindung von einem laptop-Clients in das Tomcat-server
- Schalten Sie die Netzwerk-Verbindung auf dem laptop mit dem physischen Schalter
- Warten Sie, bis Tomcat-server-Ereignisse
Wie funktioniert eine Feder FrameworkTomcat server schnell zu erkennen, dass ein client wurde getrennt oder reagiert nicht schließen der websocket?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Application Events kann Ihnen dabei helfen.
PS: Annotation-driven events
PS2: ich habe ein Beispiel-Projekt für Sie
ServletServerContainerFactoryBean einfach konfiguriert die zugrunde liegenden JSR-356 WebSocketContainer durch Spring-Konfiguration auf Start. Wenn Sie einen Blick in dir wirst sehen, es ist trivial.
Von dem, was ich sehen kann, die in Tomcat-code über den Umgang mit maxSessionIdleTimeout, die WsWebSocketContainer#backgroundProcess () - Methode wird ausgeführt, alle 10 Sekunden (default), um zu sehen, ob es abgelaufene sessions.
Vermute ich, dass auch die pings Sie senden vom server die Sitzung erscheinen aktiv, daher nicht zu helfen, mit Bezug auf die Sitzung im Leerlauf-timeout-Konfiguration.
Warum Tomcat nicht erkennen, der client wird getrennt früher, kann ich nicht wirklich sagen. In meiner Erfahrung, wenn ein Kunde schließt eine WebSocket-Verbindung, oder wenn ich das töten der browser es sofort erkannt. Auf jeden Fall mehr zu tun mit Tomcat nicht Frühling.
Den Ansatz, den ich schließlich fand, war die Implementierung einer application-layer-ping-pong-Protokolls.
p
an den client.n
ping-Nachrichten, ohne dass eine pong-Antwort, die es erzeugt ein timeout-Ereignis.n*p
Zeit.Sollte es eine viel einfachere Art und Weise der Umsetzung dieser mit Zeitüberschreitungen in den zugrunde liegenden TCP-Verbindung.