Ich erstelle eine Anwendung in Java, die einen eingebetteten Websocket-Server hat, der auf Jetty basiert. Der Client ist die Standard-Websocket-Implementierung in Google Chrome. Alles funktioniert in Ordnung, nur wenn nach einer bestimmten Zeit, in der die Verbindung geschlossen wird, keine Übertragung zwischen Server und Client erfolgt. Ich bin nicht sicher, wer die Verbindung schließt: der Steg-Server oder der Chrome-Browser.
Ich denke, die Lösung dafür besteht darin, alle x Sekunden eine Nachricht zu senden, aber ich bin offen für bessere Lösungen.
SO ... meine Fragen sind:
Ist dies etwas, das das Websocket-Protokoll erfordert, und in diesem Fall schließt der Chrome-Browser meine Verbindung?
Ist dies etwas, das mehr mit dem Steg zusammenhängt und mehr oder weniger mit dem Websocket-Protokoll zu tun hat? Wie deaktiviere ich dies in diesem Fall im Steg?
Gibt es ein anderes Problem?
Vielen Dank
UPDATE: Auch wenn ich 1 Nachricht / Sekunde sende, ist die Verbindung geschlossen
quelle
Antworten:
Als Antwort auf Ihre dritte Frage: Ihr Client möchte ohnehin in der Lage sein, vorübergehende Netzwerkprobleme zu bewältigen. Nehmen wir beispielsweise an, der Benutzer schließt seinen Laptop zwischen Besprechungen, die ihn in den Ruhezustand versetzen, oder das Netzwerk fällt einfach vorübergehend aus.
Die Lösung besteht darin,
onclose
Ereignisse auf dem Web-Socket-Client abzuhören und bei Auftreten ein clientseitiges Zeitlimit festzulegen, um die Verbindung erneut zu öffnen, z. B. in einer Sekunde:function setupWebSocket(){ this.ws = new WebSocket('wss://host:port/path'); this.ws.onerror = ...; this.ws.onopen = ...; this.ws.onmessage = ...; this.ws.onclose = function(){ setTimeout(setupWebSocket, 1000); }; }
quelle
Sie müssen von Zeit zu Zeit Ping-Nachrichten senden. Ich denke, das Standardzeitlimit beträgt 300 Sekunden. Senden eines Websocket-Ping- / Pong-Frames vom Browser
quelle
Ich fand eine andere, ziemlich schnelle und schmutzige Lösung. Wenn Sie den WebSocket auf niedriger Ebene implementieren und die
onOpen
Methode selbst implementieren, erhalten Sie ein Objekt, das dieWebSocket.Connection
Schnittstelle implementiert . Dieses Objekt verfügt über eine setMaxIdleTime- Methode, die Sie anpassen können.quelle
Sie können das Timeout-Intervall in der serverseitigen Jetty-Konfiguration mithilfe der
WebSocketServletFactory
Instanz festlegen . Zum Beispiel:WebSocketHandler wsHandler = new WebSocketHandler() { @Override public void configure(WebSocketServletFactory factory) { factory.getPolicy().setIdleTimeout(1500); factory.register(MyWebSocketAdapter.class); ... } }
quelle
Habe gerade die Lösung für mich gefunden. Was Sie einstellen möchten, ist die maxIdleTime von WebSocketServlet in Millis. Wie das geht, hängt davon ab, wie Sie Ihr Servlet konfigurieren. Mit Guice ServletModule können Sie so etwas für eine Zeitüberschreitung von 10 Stunden tun:
serve("ws").with(MyWSServlet.class, new HashMap<String, Sring>(){{ put("maxIdleTime", TimeUnit.HOURS.toMillis(10) + ""); }});
Alles <0 ist eine unendliche Leerlaufzeit, glaube ich.
quelle
Ich glaube, das ist ein Stegproblem. Ich habe keine Browser gesehen, die WebSocket-Verbindungen aufgrund von Inaktivität geschlossen haben, und ich habe auch keine anderen WebSocket-Server gefunden, bei denen WebSocket-Verbindungen zeitlich begrenzt sind.
Jetty konzentriert sich (war) hauptsächlich auf das Erstellen von HTTP-basierten Anwendungsservlets. In diesem Zusammenhang müssen HTTP-Verbindungen ziemlich aggressiv bereinigt werden, und HTTP wurde nicht für langlebige Verbindungen entwickelt, sodass ein kurzes Standardzeitlimit angemessen ist.
Ich habe das von Ihnen beschriebene genaue Problem nicht gesehen (Schließen auch bei Aktivität), aber ich sehe, dass WebSocket-Verbindungen nach 30 Sekunden Inaktivität geschlossen werden. Es ist möglich, dass in älteren Versionen von Jetty oder in der aktuellen Version aus einem anderen Grund der Timer nicht durch WebSocket-Aktivitäten zurückgesetzt wird. Um dieses Problem zu umgehen, verwende ich die setMaxIdleTime-Methode für mein BlockingChannelConnector-Objekt, um den Timeout-Wert auf Integer MAX_VALUE zu setzen.
quelle
Ich denke, dieses Timeout ist tatsächlich Teil von TCP / IP und die Lösung besteht darin, nur ab und zu leere Nachrichten zu senden.
quelle
Hier ist ein Beispiel zum Konfigurieren des Websocket-Timeouts von Jetty (der wahrscheinlichste Schuldige) mithilfe von WebSocketServlet (in Scala, sorry, aber die Syntax ist ziemlich gleich).
import javax.servlet.annotation.WebServlet import org.eclipse.jetty.websocket.servlet.{WebSocketServletFactory, WebSocketServlet} @WebServlet(name = "WebSocket Servlet") class WebsocketServlet extends WebSocketServlet { override def configure(factory: WebSocketServletFactory): Unit = { factory.getPolicy.setIdleTimeout(1000 * 3600) factory.register(classOf[ClientWebsocket]) } }
quelle
Ich habe eine ähnliche Erfahrung und glaube, dass es der Browser sein könnte, der die Sitzung abbricht. Ich habe auch das maxIdleTimeout festgelegt, aber die Sitzung wird trotzdem abgebrochen. Für mich sieht es so aus, als ob der Client (der Browser) die Sitzung zeitlich begrenzt und dann auflegt.
Ich weiß nicht, wie ich es umgehen soll.
quelle
Gleiches Problem: Verwenden Sie die Bibliothek WebSockets & sockjs-client / 1.0.3 / sockjs mit @ServerEndPoint auf der Java Server-Seite. Die Websocket-Verbindungen brachen immer wieder unterschiedlich.
Ich habe Stomp und sockJS verwendet (@ServerEndpoint verlassen), bin aber auf ein anderes Problem gestoßen, das bei SO beliebt ist - / info = 34424 - mit 404-Fehler -
Ich musste die Verwendung des XML-Ansatzes der Stomp Spring-Bibliothek aufgeben, wie an anderen Stellen vorgeschlagen. Ich habe Spring 4.2 in meinem Projekt und viele SockJS Stomp-Implementierungen funktionieren normalerweise gut mit Spring Boot-Implementierungen. Diese Implementierung von Baeldung hat funktioniert (für mich ohne Wechsel von Spring 4.2 auf 5).
Nachdem ich die in seinem Blog erwähnten Abhängigkeiten verwendet hatte, gab es mir immer noch ClassNotFoundError. Ich habe die folgende Abhängigkeit hinzugefügt, um das Problem zu beheben.
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.2.3.RELEASE</version> </dependency>
quelle
Dies funktionierte für mich, während die anderen Lösungen nicht waren!
Dies hört auf, ständig mit Ihrer EC2-Instanz verbunden zu sein. Selbst wenn Sie aufgrund eines Internetverbindungsverlusts die Verbindung verlieren, wird die Verbindung zum aktiv funktionierenden Kernel automatisch wiederhergestellt, wenn Sie einen neuen WLAN-Zugang erhalten.
Vergessen Sie auch nicht, Ihren Jupyter in einem tmux-Konto oder einem ngnix oder einer anderen Umgebung wie dieser zu starten.
Hoffe das hilft!
quelle
Da bei @Doua Beri die Verbindung auch bei 1-Hz-SENDs geschlossen wird, kann dies an Größenbeschränkungen für Nachrichten liegen.
Diese Passage aus Spring's WebSockets kann nützlich sein, mit meinem Schwerpunkt ...
quelle