Detectando HTTP Fechar usando INET
Pergunta
No meu aplicativo Mochiweb, estou usando uma solicitação HTTP de longa data. Eu queria detectar quando a conexão com o usuário morreu, e eu descobri como fazer isso fazendo:
Socket = Req:get(socket),
inet:setopts(Socket, [{active, once}]),
receive
{tcp_closed, Socket} ->
% handle clean up
Data ->
% do something
end.
Isso funciona quando: o usuário fecha sua guia/navegador ou atualiza a página. No entanto, quando a conexão com a Internet morre de repente (digamos que o sinal WiFi perdeu de repente), ou quando o navegador trava anormalmente, não consigo detectar um TCP fechado.
Estou perdendo alguma coisa, ou há outra maneira de conseguir isso?
Solução
Existe um Protocolo Keepalive TCP e pode ser ativado com inet:setopts/2
sob a opção {keepalive, Boolean}
.
Eu sugeriria que você não o use. O tempo limite de Keep-Alive e as retiradas máximas tendem a ser amplas do sistema e, afinal, é opcional. O uso de tempo limite no nível do protocolo é melhor.
O protocolo HTTP tem o Timeout de solicitação de código de status que você pode enviar ao cliente se parecer morto.
Confira o after
Cláusula em blocos de recebimento que você pode usar no tempo limite esperando por dados ou usar o módulo do timer ou usar erlang:start_timer/3
. Todos eles têm diferentes características de desempenho e custos de recursos.
Outras dicas
Não há um padrão "mantenha vivo" (mas pode ser ativado se suportado) Protocolo sobre TCP: Caso haja uma falha de conexão quando nenhum dado é trocado, isso se traduz em uma "falha silenciosa". Você precisaria explicar esse tipo de falha por si mesmo, por exemplo, implementar alguma forma de sondagem de conexão.
Como isso afeta o HTTP? O HTTP é um protocolo sem estado - isso significa que toda solicitação é independente de todos os outros. A funcionalidade "Keep Alive" do HTTP não muda que o IE "falha silenciosa" ainda pode ocorrer.
Somente quando os dados são trocados Essa condição pode ser detectada (ou quando o TCP Keep Alive estiver ativado).
Eu sugeriria enviar as mensagens do nível do aplicativo, mantenha as mensagens vivas sobre o codificação HTTP. Peça ao seu cliente/servidor inteligente o suficiente para entender as mensagens de Keep Alive e ignore-as se chegarem a tempo ou fechar e restabelecer a conexão novamente.