У меня довольно ресурсоемкий CGI, которому требуется довольно много времени, чтобы начать отправку данных. Мы видели довольно много случаев, когда нетерпеливые люди перезагружали пару раз, что затем запускало дополнительные запуски CGI для загрузки, или случаи, когда клиент истекает и разрывает соединение, но CGI продолжает работать.
Есть ли хороший способ определить, когда это произошло? Это даже не обязательно должно быть внутри самого CGI (и, вероятно, лучше, если это не так - он передается другой программе, над которой я не контролирую), но может быть заданием cron, которое запускается так часто искать мертвые связи, чтобы пожать.
В настоящее время я использую Apache, но это такая проблема, что я хотел бы запустить какой-нибудь другой веб-сервер, если на нем есть средства для ее решения (или способ позволить мне отслеживать проблему).
Обычно вы не можете обнаружить разорванное соединение, пока не начнете писать пользователю. В противном случае ваш процесс продолжит свою работу, не заметив прерывания соединения со стороны пользователя. Эта почта связано, даже если речь идет о PHP. Концепция должна быть такой же.
Вы можете попробовать:
Если вы сохраняете текущие выполняемые задания в базе данных, вы можете сохранить идентификатор запроса и / или IP-адрес клиента. Таким образом, вы можете обнаруживать и игнорировать повторяющиеся запросы к одному и тому же ресурсу, сообщая пользователю, что ваш запрос находится в обработке.
Старый вопрос, но у меня была такая же проблема, и я решил проверить, установлено ли соединение:
В моем случае я запускаю один сценарий bash на сервере .. переменные env экспортируются с помощью mod_cgi. Я считаю, что это решение будет работать для любой программы / сценария, запущенного на 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
Предупреждение: эта информация может быть устаревшей. См. Последний абзац.
Я помню, что у меня была такая же проблема, и я решил ее с помощью nph (без синтаксического заголовка) CGI-скрипт.
Обычно apache собирает все заголовки из вашего скрипта и, закончив чтение заголовков, изменяет их некоторыми стандартными заголовками, которые вы не предоставили. Это также означает, что до тех пор, пока вы не завершите заголовки, apache вообще ничего не отправляет клиенту.
С помощью сценария nph вам нужно будет предоставить все заголовки, но apache немедленно отправит их клиенту, а ваш сценарий CGI отправит SIGPIPE после отключения клиента. Так что вы можете отправить X-Slowly-Counting-Part-nnn: yes
заголовок каждые несколько секунд, чтобы предотвратить тайм-ауты на клиенте, и вы получите уведомление, если клиенты разорвут соединение.
Это по-прежнему оставляет проблему, вам придется сначала отправить HTTP-статус, но если вы отправите Content-Length: 0 или, возможно, Content-Length: 1 и закроете соединение без отправки какого-либо контента, ваш файл загрузчик должен предположить сетевую ошибку и действовать соответствующим образом.
Вам, вероятно, придется передавать вывод другой программы через ваш процесс, но это не должно сильно снижать производительность, по крайней мере, если вы работаете в Linux и используете sendfile(2)
системный вызов.
Проблема со всем этим в том, что я использовал его как минимум 10 лет назад, вероятно, на Apache 1.3, и поискал в Google apache cgi nph
ничего полезного не принес. Так что, возможно, функция nph тем временем была удалена - но тогда, может быть, и нет, признаю, я не очень сильно смотрел.