Posso detectar quando um cliente desconectou de um CGI?

4

Eu tenho um CGI bastante intensivo em recursos que leva muito tempo para começar a enviar dados. Vimos alguns casos em que pessoas impacientes recarregam algumas vezes, o que aciona execuções adicionais do CGI a ser carregado ou casos em que o cliente expira e desconecta a conexão, mas o CGI continua em execução.

Existe alguma boa maneira de detectar quando isso aconteceu? Ele nem precisa estar dentro do próprio CGI (e provavelmente melhor se não for - ele entrega para outro programa que eu não tenho controle), mas poderia ser um cron job que é executado de vez em quando para procurar conexões mortas para colher.

Atualmente estou usando o Apache, mas isso é um problema que eu estaria disposto a executar algum outro servidor web, se tiver disposições para lidar com isso (ou uma maneira de me deixar monitorar o problema).

    
por Joe H. 23.05.2015 / 12:07

3 respostas

4

Normalmente, você não pode detectar uma conexão interrompida até começar a escrever de volta para o usuário. Caso contrário, seu processo continuará fazendo seu trabalho sem perceber a interrupção da conexão do lado do usuário. Este post está relacionado mesmo que fale sobre PHP. O conceito deve ser o mesmo.

Existem coisas possíveis que você pode tentar:

  1. Faça o trabalho demorado em segundo plano. Quando um usuário solicita o CGI, não execute a tarefa como uma chamada de bloqueio normal. Basta retornar qualquer coisa ao usuário para informar que a solicitação está sendo processada. É claro que você precisa encontrar alguma maneira de atualizar a exibição ou fornecer outra página para verificar o status da tarefa usando algum ID de solicitação ou IP.
  2. Envie os dados de volta ao cliente o mais rápido possível e saia se não enviar (indicação de conexão interrompida). Você pode, por exemplo, enviar o progresso do trabalho a cada poucos segundos ou minutos.

Se você salvar os trabalhos atualmente em execução em um banco de dados, poderá salvar o ID da solicitação e / ou o endereço IP do cliente. Assim, você pode detectar e ignorar solicitações duplicadas para o mesmo recurso informando ao usuário "o seu pedido está sob processamento".

    
por 23.05.2015 / 12:33
2

Pergunta antiga, mas tive o mesmo problema e resolvi verificar se a conexão foi estabelecida:

No meu caso, estou executando um script bash no servidor. as variáveis env são exportadas por mod_cgi Eu acredito que esta solução funcionará para qualquer programa / script em execução no CGI

ss -nt state established "( sport = :$SERVER_PORT and dport = $REMOTE_ADDR:$REMOTE_PORT )" 2>/dev/null | grep -q "$REMOTE_ADDR:$REMOTE_PORT"
if [ "$?" -ne '0' ]; then
     # Client closed browser/connection
fi
    
por 16.02.2017 / 01:54
2

Aviso: essas informações podem estar obsoletas. Veja o último parágrafo.

Lembro-me de ter tido o mesmo problema e resolvi-lo com um nph (sem cabeçalho de análise) Script CGI.

Normalmente, o apache coleta todos os cabeçalhos do seu script e, ao terminar de ler os cabeçalhos, os altera com alguns cabeçalhos padrão que você não forneceu. O que também significa, contanto que você não termine os cabeçalhos, o apache não envia nada para o cliente.

Com um script nph, você terá que fornecer todos os cabeçalhos, mas o apache irá enviá-los ao cliente imediatamente, e enviará ao seu script CGI um SIGPIPE assim que o cliente desconectar. Assim, você pode enviar um pouco do cabeçalho X-Slowly-Counting-Part-nnn: yes a cada poucos segundos, para evitar tempos limites no cliente, e você será notificado se os clientes violarem a conexão.

Isso ainda deixa o problema, você terá que enviar primeiro o Status HTTP, mas se você enviar um 'Content-Length: 0', ou talvez um 'Content-Length: 1' e fechar a conexão sem enviar nenhum conteúdo , o seu arquivo downloader deve assumir um erro de rede e agir de acordo.

Você provavelmente terá que enviar a saída do outro programa através do seu processo, mas isso não deve ser um grande impacto no desempenho, pelo menos se você estiver no Linux e usar a chamada do sistema sendfile(2) .

O problema com tudo isso é que eu usei pelo menos 10 anos atrás, provavelmente no Apache 1.3, e procurar apache cgi nph não resultou em nada útil. Então, talvez o recurso nph foi removido no entretanto - mas, talvez, não, eu admito que não parecia muito difícil.

    
por 23.05.2015 / 19:30