wake-up-neo.com

Die Verbindung wird automatisch geschlossen

Ich baue eine Anwendung in Java mit einem eingebetteten Websocket-Server auf der Basis von Jetty. Der Client ist die standardmäßige Websocket-Implementierung in Google Chrome. Alles funktioniert einwandfrei, nur wenn keine Übertragung zwischen beiden stattfindet Server und Client nach einer bestimmten Zeit wird die Verbindung geschlossen. Ich bin nicht sicher, wer die Verbindung schließt: der Jetty-Server oder der chrome browser.

Ich denke, die Lösung besteht darin, alle x Sekunden eine Nachricht zu senden, aber ich bin offen für bessere Lösungen.

SO ... meine Fragen sind:

  1. Ist dies etwas, was das Websocket-Protokoll erfordert und in diesem Fall schließt der chrome browser meine Verbindung?

  2. Hat dies mehr oder weniger mit dem Websocket-Protokoll zu tun? In diesem Fall, wie deaktiviere ich das im Steg?

  3. Gibt es ein anderes Problem?

Vielen Dank

PDATE: auch wenn ich 1 nachricht/sekunde sende ist die verbindung noch geschlossen

66
Doua Beri

Zur Beantwortung Ihrer dritten Frage: Ihr Client möchte in der Lage sein, vorübergehende Netzwerkprobleme zu bewältigen, z. Nehmen wir an, der Benutzer schließt seinen Laptop zwischen Besprechungen, die ihn in den Ruhezustand versetzen, oder das Netzwerk fällt vorübergehend aus.

Die Lösung besteht darin, onclose Ereignisse auf dem Web-Socket-Client abzuhören und, wenn sie auftreten, eine clientseitige Zeitüberschreitung festzulegen, um die Verbindung erneut zu öffnen, beispielsweise 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);
    };
}
38
Ant Kutschera

Sie müssen von Zeit zu Zeit Ping-Nachrichten senden. Ich denke, das Standard-Timeout beträgt 300 Sekunden. Senden von Websocket-Ping/Pong-Frame vom Browser

15

Ich fand eine andere, ziemlich schnelle und schmutzige Lösung. Wenn Sie den Low-Level-Ansatz zum Implementieren von WebSocket verwenden und die onOpen -Methode selbst implementieren, erhalten Sie ein Objekt, das die WebSocket.Connection Schnittstelle. Dieses Objekt hat eine setMaxIdleTime Methode, die Sie anpassen können.

9
LeoR

Sie können das Zeitlimitintervall in der serverseitigen Konfiguration von Jetty mithilfe der WebSocketServletFactory-Instanz festlegen. Beispielsweise:

        WebSocketHandler wsHandler = new WebSocketHandler()
        {
            @Override
            public void configure(WebSocketServletFactory factory)
            {
                factory.getPolicy().setIdleTimeout(1500);
                factory.register(MyWebSocketAdapter.class);
                ...
            }
        }
7
user3499459

Habe gerade die Lösung für mich gefunden. Was Sie festlegen 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 für ein Timeout von 10 Stunden so etwas tun:

serve("ws").with(MyWSServlet.class, 
new HashMap<String, Sring>(){{ put("maxIdleTime", TimeUnit.HOURS.toMillis(10) + ""); }});

Alles, was <0 ist, ist unendliche Leerlaufzeit, glaube ich.

4
AkaZn

Ich glaube, das ist eine Angelegenheit für Anlegestellen. Ich habe keine Browser gesehen, die WebSocket-Verbindungen aufgrund von Inaktivität geschlossen haben, und auch keine anderen WebSocket-Server, bei denen das Zeitlimit für WebSocket-Verbindungen überschritten wurde.

Jetty konzentriert sich (war) in erster Linie auf die Erstellung 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 Problem nicht genau gesehen (Schließen trotz Aktivität), aber es werden WebSocket-Verbindungen nach 30 Sekunden Inaktivität geschlossen. 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 dies zu umgehen, verwende ich die setMaxIdleTime-Methode für mein BlockingChannelConnector-Objekt, um den Timeout-Wert auf Integer MAX_VALUE festzulegen.

3
kanaka

Hier ist ein Beispiel, wie Sie das Websocket-Timeout von Jetty (wahrscheinlich der Täter) mit WebSocketServlet konfigurieren (in scala leider, 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])
  }
}
2
user1338062

Ich denke, diese Zeitüberschreitung ist Teil von TCP/IP und die Lösung besteht darin, nur gelegentlich leere Nachrichten zu senden.

2
David Grayson

Ich habe eine ähnliche Erfahrung und ich glaube, dass es der Browser sein könnte, der die Sitzung abbricht. Ich habe auch das maxIdleTimeout festgelegt, aber die Sitzung wird trotzdem beendet. Für mich sieht es so aus, als würde der Client (der Browser) die Sitzung beenden und dann auflegen.

Ich weiß nicht, wie ich das umgehen soll.

1
AndersW