2009-12-30 19 views
6

En mi aplicación mochiweb, estoy usando una solicitud HTTP largamente retenida. Quería detectar cuando la conexión con el usuario murió, y me di cuenta de cómo hacer que al hacer:Detectando HTTP close usando inet

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

Esto funciona cuando: el usuario cierra su pestaña/navegador o actualiza la página. Sin embargo, cuando la conexión a Internet muere repentinamente (digamos que la señal wifi se pierde de repente), o cuando el navegador falla de manera anormal, no puedo detectar un tcp cercano.

¿Me falta algo, o hay alguna otra forma de lograrlo?

Respuesta

2

Hay un TCP keepalive protocol y se puede habilitar con inet:setopts/2 en la opción {keepalive, Boolean}.

Le sugiero que no lo use. El tiempo de espera keep-alive y max-retries tiende a ser de todo el sistema, y ​​es opcional después de todo. Usar tiempos de espera en el nivel de protocolo es mejor.

El protocolo HTTP tiene el status code Request Timeout que puede enviar al cliente si parece muerto.

Consulte la cláusula after en los bloques de recepción que puede usar para agotar el tiempo de espera de datos, o utilice el módulo de temporizador, o use erlang:start_timer/3. Todos ellos tienen diferentes características de rendimiento y costos de recursos.

+0

Consideré usar la cláusula posterior, pero en este caso, mi proceso podría ser un proceso de hibernación. ¿Seguiría funcionando la cláusula posterior para un proceso de hibernación? – jeffreyveon

+0

No, no lo haría. Un proceso de hibernación se activa cuando se le envía un mensaje. No hay un tiempo de espera de hibernación, por lo que debe recibir un mensaje demorado para que se despierte. – Christian

1

No hay un protocolo predeterminado "keep alive" (pero puede ser enabled if supported) sobre TCP: en caso de que haya un error de conexión cuando no se intercambian datos, esto se traduce en un "error silencioso". Debería justificar este tipo de error usted mismo, p. implementar alguna forma de sondeo de conexión.

¿Cómo afecta esto a HTTP? HTTP es un protocolo sin estado; esto significa que cada solicitud es independiente de todas las demás. La funcionalidad "mantener activo" de HTTP no cambia, es decir, que aún puede producirse un "error silencioso".

Solo cuando se intercambian datos se puede detectar esta condición (o cuando TCP Keep Alive está habilitado).

0

Sugeriría enviar los mensajes de mantener vivo de la aplicación a través de la codificación por fragmentos HTTP. Haga que su cliente/servidor sea lo suficientemente inteligente como para comprender los mensajes de mantener vivo e ignórelos si llegan a tiempo o cierran y restablecen la conexión nuevamente.

Cuestiones relacionadas