HTTP Proxy / FastCGI / SCGI не закрывает соединение при отключении клиента - ошибка или функция? - PullRequest
2 голосов
/ 30 августа 2009

Я работаю над поддержкой Comet для CppCMS Framework через длинные опросы XMLHttpRequest. Во многих случаях такой запрос закрывается клиентом до того, как был получен какой-либо ответ от сервера - например, страница закрыта, пользователь переходит на другую страницу или просто обновляется.

На стороне сервера я ожидаю, что получу уведомление о том, что соединение разорвано. Я протестировал приложение через 3 разъема: FastCGI, SCGI и простой HTTP Proxy.

Из 3 основных веб-серверов UNIX, Apache2, lighttpd и Nginx, закрылся только последний соединение, как и ожидалось, позволяло моему приложению удалить запрос из очереди ожидания - это работало как для коннекторов FastCGI, так и для HTTP-прокси. (Nginx по умолчанию не имеет модуля scgi).

Другие, Apache и Lighttpd не закрывают соединение и не сообщают бэкэнду об отключении клиенты, продолжить, как будто клиент все еще на линии. Это происходит для всех 3 поддерживаемых API: FastCGI, SCGI и HTTP Proxy.

Я открыл проблему для Lighttpd , но что Еще больше меня удивляет тот факт, что Apache - зрелый и хорошо поддерживаемый веб-сервер как lighttpd и не раскрывает серверную часть, на которую ушел клиент.

Вопросы:

  1. Это ошибка или это особенность? Есть ли причина не закрывать соединение между веб-сервером и серверной частью приложения?
  2. Существуют ли реальные приложения Comet, работающие за этими серверами через бэкэнды FastCGI / SCGI / HTTP-Proxy?
  3. Если вышеизложенное верно, как они справляются с этой проблемой? Я понимаю, что могу тайм-аутить все соединения каждые 10 секунд, но я бы хотел, чтобы они простаивали до тех пор, пока клиент слушает - потому что это позволяет легче масштабировать - каждое соединение очень дешевое - стоимость только открытого сокета.

Спасибо!

Ответы [ 2 ]

4 голосов
/ 06 сентября 2009

(1) Или, более конкретно, выпадение из деталей реализации.

Соединение TCP / IP не требует постоянного потока трафика туда и обратно. Таким образом, невозможно узнать, что клиент ушел, если (а) клиент не сообщит вам, что закрывает соединение, или (б) тайм-аут.

(2) Я не особенно знаком с Comet или CppCMS. Но, да, за упомянутыми веб-серверами работают всевозможные серверы CMS, и им всем приходится иметь дело с этой проблемой (и да, это боль).

(3) Тайм-ауты - единственный способ, но вы можете, так сказать, уменьшить боль. Попросите клиента пропинговать сервер через соединение каждые N секунд, если в противном случае нет активности. Не нужно ничего делать, и вы можете прикрепить материал к ответу; уведомления о одновременных изменениях или что вам нужно.

Вы правы в том, что удивительно, что mod_fastcgi не поддерживает сообщение бэкэнду о том, что Apache обнаружил разъединение или истекло время ожидания соединения. И ты не первый, кто встревожен.

Второй патч на этой странице должен исправить эту конкретную проблему:

http://osdir.com/ml/web.fastcgi.devel/2006-02/msg00015.html

0 голосов
/ 06 сентября 2009

http://ncannasse.fr/blog/tora_comet

У меня нет конкретной информации для вас, но в этой статье упоминается, что они могут обнаружить, когда клиент отключился от Apache. Смотри tora.Queue. И похоже, что источник доступен в neko CVS, так что вы можете найти некоторые подсказки там. Удачи.

...