2009-12-30 11 views
6

Nella mia applicazione mochiweb, sto usando una richiesta HTTP da molto tempo. Ho voluto rilevare quando il collegamento con l'utente è morto, e ho capito come fare che facendo:Rilevamento della chiusura HTTP usando inet

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

Questo funziona quando: utente chiude la sua scheda/browser o aggiorna la pagina. Tuttavia, quando la connessione Internet muore improvvisamente (ad esempio, il segnale wifi si interrompe all'improvviso), o quando il browser si arresta in modo anomalo, non sono in grado di rilevare una chiusura tcp.

Mi manca qualcosa o esiste un altro modo per raggiungere questo obiettivo?

risposta

2

C'è un TCP keepalive protocol e può essere abilitato con inet:setopts/2 sotto l'opzione {keepalive, Boolean}.

Suggerirei di non utilizzarlo. Il timeout keep-alive e il numero massimo di tentativi tende ad essere esteso al sistema, dopotutto è facoltativo. L'utilizzo dei timeout a livello di protocollo è migliore.

Il protocollo HTTP ha il status code Request Timeout che è possibile inviare al client se sembra morto.

Controllare la clausola after nei blocchi di ricezione che è possibile utilizzare per sospendere i dati in attesa o utilizzare il modulo timer o utilizzare erlang:start_timer/3. Hanno tutti caratteristiche di prestazioni e costi delle risorse diversi.

+0

Ho considerato l'utilizzo della clausola after, ma in questo caso, il mio processo potrebbe essere un processo di ibernazione. La clausola after funzionerebbe ancora per un processo di ibernazione? – jeffreyveon

+0

No, non lo farebbe. Un processo di ibernazione si attiva quando viene inviato un messaggio. Non vi è alcun timeout di sospensione, quindi invia un messaggio in ritardo per svegliarti. – Christian

1

Non c'è un protocollo predefinito "mantenere in vita" (ma può essere enabled if supported) su TCP: nel caso ci sia un errore di connessione quando i dati non vengono scambiati, questo si traduce in un "fallimento silenzioso". Dovresti tenere conto di questo tipo di errore da solo, ad es. implementare qualche forma di sondaggio di connessione.

In che modo influisce su HTTP? HTTP è un protocollo stateless - questo significa che ogni richiesta è indipendente l'una dall'altra. La funzionalità "keep alive" di HTTP non cambia, ad esempio "l'errore silenzioso" può ancora verificarsi.

Solo quando i dati vengono scambiati è possibile rilevare questa condizione (o quando TCP Keep Alive è abilitato).

0

Suggerirei di inviare il livello dell'applicazione mantieni i messaggi attivi su HTTP chunked-encoding. Avere il tuo client/server abbastanza intelligente da capire i messaggi keep alive e ignorarli se arrivano in orario o chiudi e ristabilire di nuovo la connessione.