2009-12-30 18 views
6

In meiner Mochiweb-Anwendung verwende ich eine lange gehaltene HTTP-Anfrage. Ich wollte erkennen, wenn die Verbindung mit dem Benutzer gestorben, und ich herausgefunden, wie das zu tun, indem Sie:Erkennen von HTTP mit inet schließen

Socket = Req:get(socket), 
inet:setopts(Socket, [{active, once}]), 
receive 
    {tcp_closed, Socket} -> 
      % handle clean up 
    Data -> 
      % do something 
end. 

Dies funktioniert, wenn: Benutzer seine Reiter/Browser schließt oder aktualisiert die Seite. Wenn jedoch die Internetverbindung plötzlich abbricht (zB wenn das WLAN-Signal plötzlich verloren geht) oder wenn der Browser abnormal abstürzt, kann ich keinen TCP-Abschluss erkennen.

Fehle ich etwas oder gibt es einen anderen Weg, dies zu erreichen?

Antwort

2

Es gibt eine TCP keepalive protocol und es kann mit inet:setopts/2 unter der Option {keepalive, Boolean} aktiviert werden.

Ich würde vorschlagen, dass Sie es nicht verwenden. Das Keep-Alive-Timeout und Max-Retries sind systemweit, und es ist schließlich optional. Die Verwendung von Timeouts auf Protokollebene ist besser.

Das HTTP-Protokoll hat die status code Request Timeout, die Sie an den Client senden können, wenn es tot scheint.

Überprüfen Sie die Klausel after in Empfangsblöcken, die Sie verwenden können, um das Warten auf Daten zu Timeout oder verwenden Sie das Timer-Modul, oder verwenden Sie erlang:start_timer/3. Sie alle haben unterschiedliche Leistungsmerkmale und Ressourcenkosten.

+0

Ich dachte über die Verwendung der After-Klausel, aber in diesem Fall könnte mein Prozess einen Winterschlaf-Prozess sein. Würde die after-Klausel noch für einen Winterschlaf funktionieren? – jeffreyveon

+0

Nein, würde es nicht. Ein Ruhezustand wird aktiviert, wenn eine Nachricht an ihn gesendet wird. Es gibt kein Zeitlimit für den Ruhezustand, daher sollten Sie eine verzögerte Nachricht erhalten, damit Sie aufwachen können. – Christian

1

Es gibt keine Standardeinstellung "keep alive" (kann aber enabled if supported sein) Protokoll über TCP: Wenn ein Verbindungsfehler vorliegt, wenn keine Daten ausgetauscht werden, führt dies zu einem "stillen Fehler". Sie müssten diese Art von Fehler selbst berücksichtigen, z. Implementieren Sie eine Form der Verbindungssuche.

Wie wirkt sich dies auf HTTP aus? HTTP ist ein zustandsloses Protokoll - das bedeutet, dass jede Anfrage unabhängig von einander ist. Die "Keep Alive" -Funktionalität von HTTP ändert sich nicht, d. H. "Silent Failure" kann immer noch auftreten.

Nur wenn Daten ausgetauscht werden kann diese Bedingung erkannt werden (oder wenn TCP Keep Alive aktiviert ist).

0

Ich würde vorschlagen, die Anwendungsebene Keep Alive-Nachrichten über HTTP Chunked-Codierung senden. Lassen Sie Ihren Client/Server intelligent genug sein, um die Keep Alive-Nachrichten zu verstehen und ignorieren Sie sie, wenn sie pünktlich ankommen oder schließen und die Verbindung erneut herstellen.

Verwandte Themen