Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2013.03.22;
Скачать: CL | DM;

Вниз

Как правильно задать вопрос...   Найти похожие ветки 

 
Дмитрий С ©   (2012-05-24 12:50) [0]

... когда не знаешь как? В общем, в этой тебе будет два вопроса в одном.
Писал я программу под debian на php, которая является небольшим http сервером (почему такой выбор - вопрос отдельной темы). Когда все было готово, это все отлично работало, если открывать в Файерфоксе или в Хроме. А вот с IE появилась проблема (а нужно чтобы именно в нем открывалось). Само содержание сайта, который транслировал мой http сервер, - это страничка, которая раз в секунду делает запрос и отображает его данные. Делает она это с помощью XMLHTTPRequest. Так вот, в этом самом IE иногда (примерно в 1 случае из 10) запрос зависал. Т.е. жму F5 - открывается страница, первый запрос, второй запрос, третий - завис, четвертый нормально и так далее все нормально. Жму снова F5 - все запросы работают нормально.
Естественно на то, что 9 IE (работающий в режиме совместимости с IE8) глючит я подумал в последнюю очередь и начал разбираться со своим сервером. В итоге вот к чему пришел:
Иногда (как раз тогда когда зависает), в одном из keep-alive соединении мой сервер читает очередной http заголовок, а тело post запроса прочитать не может (функция select не срабатывает, recv тоже говорит что данных нет). Манипуляции с блокирующим и неблокирующем режимом ни к чему не привели. Далее я поставил на windows (там где браузер) WireShark. В нем я заметил, что IE разбивает запрос на два пакета - заголовки и тело POST запроса (тело у меня маленькое). А также заметил, что тогда, когда происходит зависание, IE посылает заголовки, но тело запроса не посылает (вывод сделан но основе того, что в WireShark нет этого пакета, а в аналогичных независших соединениях он есть). В итоге сделал принудительное правило - один запрос - одно соединение, т.е. отключил режим keep-alive. Но это костыль, я не верю, что IE 9 имеет такой глюк, однозначно проблема где-то у меня, и мне хочется в ней разобраться, хотя бы знать причину.

Основной вопрос в том, как искать помощи по этой проблеме? Ну и что посоветуете по проблеме, что еще попробовать диагностировать?


 
Омлет ©   (2012-05-24 13:05) [1]


> как искать помощи по этой проблеме?

Для начала код выложить.


 
KSergey ©   (2012-05-24 13:34) [2]

А может проблема вовсе не в сервере (ну раз уж мы доверились WireShark), а в  особенностях написания HTML-кода для IE?
Можно попробовать почитать что-то на эту тему, может кто-то сталкивался.
Ну в самом деле: если на сервер запросы не приходят - то врятли прямо вот сервер виноват. (как вариант - можно сварганить по-быстрому простой скриптик, возвращающий точно такой же HTML-код, и запихать его на любой промышленный WEB-сервер типа апач и посмотреть что будет?


 
Омлет ©   (2012-05-24 14:29) [3]

> KSergey ©   (24.05.12 13:34) [2]
> HTML


Причем тут html? У автора с аяксом проблема.

> Дмитрий С ©

Кстати, прочему post, а не get, если ты просто запрашиваешь данные?


 
БарЛог ©   (2012-05-24 14:40) [4]

> Причем тут html? У автора с аяксом проблема.
+1

Код надо бы.


 
Дмитрий С ©   (2012-05-24 15:24) [5]


> Для начала код выложить.

Код очень большой. Я попробую убрать все лишнее, что не влияет на проявление ошибки. Но это займет время. Может, кстати? и причину при этом найду.


 
знайка   (2012-05-24 15:42) [6]

Код скрипта для начала.
Коли данных нет в транспорте, значит их не выслали.


 
han_malign   (2012-05-24 16:00) [7]

зависает наглухо или таки есть место для alert(oXMLHttpRequest.status)?


 
KSergey ©   (2012-05-24 16:40) [8]

> Омлет ©   (24.05.12 14:29) [3]
> Причем тут html? У автора с аяксом проблема.

Ну я HTML употребил в том смысле, что надо бы разобраться с кодом, приходящим на клиента и на нем (не)исполняющемся.
Ну если исходить из гипотезы, что запросы от клиента не уходят - то, очевидно, надо сначала запросов добиться, сервер-то тут как бы не при делах пока.

Или я что-то недогоняю?


 
Дмитрий С ©   (2012-05-24 17:02) [9]


> Код скрипта для начала.


 var req = mod.request;
 MakeRequest = function () {
  if (RTimeout) {
   clearTimeout(RTimeout);
   RTimeout = false;
  }

           //console.log("Make request ");

           request_num = (request_num + 1) % 0xFFFF;
           current_status.num = request_num + 1;// этот объект всего с одним полем

           req.postP(
   "live.php",
               current_status,
   function (status, text) {
                   document.getElementById("live_info").firstChild.data = ((text&&text.live_info)?text.live_info:(status));
                   if (text && text.num && text.num == current_status.num) {
                       ProcessRequest(status, text);
                   }
                   RTimeout = setTimeout(MakeRequest, 1000);
               }
  );
 };




mod.request.postP  = function (uri, postdata, oncomplete) {
if (typeof(postdata)=="object") postdata = postdata.urlEncoded();
return mod.request.request({"method":"POST", "uri":uri, "postdata":postdata, "oncomplete":oncomplete, "parse":true});
}



mod.request.request = function (params) {
var method = params["method"]?params["method"]:"GET";
var uri = params["uri"]?params["uri"]:document.location;
var timeout = params["timeout"]?params["timeout"]*1000:10000;
var postdata = params["postdata"]?params["postdata"]:null;
var parseNeeded = params["parse"]?true:false;

var req = new XMLHttpRequest();
req.open(method, uri, true)
//req.setRequestHeader("Accept", "text/javascript");
if (postdata) {
 req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
}
req.send(postdata);
var int_interval = 50, int_count = 0;
var int = setInterval(function () {
 int_count++;
 var
  isok=(req.readyState==4), // это условие для зависших запросов не выполняется
  istimeout=(int_count * int_interval > timeout),
  status;
 if (isok || istimeout) {
  clearInterval(int);
  int = false;
  if (isok) {
   status=req.status;
  }
  else if (istimeout) {
   req.abort();
   status="timeout";
  }
           var text;
           if (status != 200)
               console.log(status);
           text = status == 200?req.responseText:"";
  if (parseNeeded) {
   text = mod.request.parseResult(status, text);
   if (text === null) {
    status = "parse_error";
   }
  }
  //if (!(JS.is_unloaded)) { // не вызываем обработчик, если пользователь ушел со страницы
   if (params["oncomplete"]) {
    params["oncomplete"].apply(params["oncomplete"], [status, text]);
   }
  //}
 }
 
}, int_interval);
return {
 abort: function () {
  if (int!==false) {
   clearInterval(int);
   int = false;
   try {req.abort();}catch(dummy){};
   if (params["oncomplete"]) {
    params["oncomplete"].apply(params["oncomplete"], ["aborted", null]);
   }
  }
 },
 request: req
};
};



if (typeof XMLHttpRequest === "undefined") {
XMLHttpRequest = function() {
 try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); }
 catch(e) {}
 try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
 catch(e) {}
 try { return new ActiveXObject("Msxml2.XMLHTTP"); }
 catch(e) {}
 try { return new ActiveXObject("Microsoft.XMLHTTP"); }
 catch(e) {}
 return Err("This browser does not support XMLHttpRequest.");
};
}


Как то так.


> han_malign   (24.05.12 16:00) [7]
> зависает наглухо или таки есть место для alert(oXMLHttpRequest.
> status)?

наглухо не виснет. req.readyState не становится равен 4. Браузер ведет себя так, как будто он отправил POST и ждет ответа.


> Ну если исходить из гипотезы, что запросы от клиента не
> уходят - то, очевидно, надо сначала запросов добиться, сервер-
> то тут как бы не при делах пока.

они уходят видимо, но не доходят. IE в заголовках запроса даже указывает Content-Length: 5, а тело где-то теряется. Или IE не отправляет, или какая нить прога у меня сбрасывает пакет или еще что: WireShark пакет вообще не показывает.


 
Дмитрий С ©   (2012-05-24 17:05) [10]


> Ну если исходить из гипотезы, что запросы от клиента не
> уходят - то, очевидно, надо сначала запросов добиться, сервер-
> то тут как бы не при делах пока.

Я вот тоже не догоняю. в других браузерах все работает отлично. и в IE работает отлично если сбрасывать соединение после каждого запроса, а если использовать режим keep-alive для соединений - ИНОГДА возникает эта пресловутая потеря пакета.


 
Евгений Кузнецов   (2012-05-24 18:18) [11]


> Кстати, прочему post, а не get, если ты просто запрашиваешь
> данные?

POST запросы гарантировано не кешируются никем.


 
KSergey ©   (2012-05-24 18:26) [12]

> Дмитрий С ©   (24.05.12 17:05) [10]

Может поискать вот так?
http://www.google.ru/search?q=web+server+keep-alive

Например вот такое что-то выискивается, мне правда не хватает познаний понять имеет отношение к делу или нет

http://support.microsoft.com/kb/813827


 
Дмитрий С ©   (2012-05-24 19:35) [13]


> Например вот такое что-то выискивается, мне правда не хватает
> познаний понять имеет отношение к делу или нет

Мне вот тоже не хватает.

Обидно то, что глюк пропал сегодня при неопределенных обстоятельствах. Никаких значимых изменений я не вносил. Буду ждать нового проявления.


 
Дмитрий С ©   (2012-05-24 23:29) [14]

Появился снова. Исследую дальше.
Тотже скрипт с теме же настройками я перенес на такой же debian, только на виртуальную машину - ошибка не возникает, проверил раз 50. На реальном дебиане возникает. Я уже даже не знаю что думаю.


 
DVM ©   (2012-05-24 23:34) [15]

В IE есть ограничение на количество посылаемых через XMLHTTPRequest запросов. Т.е если их относительно много посылать с какого то момента все перестает работать. Потом прочухивается и потом опять перестает. Есть какие то обходные пути для этого и даже библиотеки какие то. Сам сталкивался с этим.


 
antonn ©   (2012-05-25 00:09) [16]


> они уходят видимо, но не доходят. IE в заголовках запроса
> даже указывает Content-Length: 5, а тело где-то теряется.
>  Или IE не отправляет, или какая нить прога у меня сбрасывает
> пакет или еще что: WireShark пакет вообще не показывает.
>

у меня KIS много и часто блокирует POST-запросов, замучался даже на локалхосте отлаживать сайт. Браузер вроде как отправляет данные, но в сеть ничего не уходит, и браузер висит чего-то ожидая.


 
Дмитрий С ©   (2012-05-25 01:11) [17]


> у меня KIS много и часто блокирует POST-запросов, замучался
> даже на локалхосте отлаживать сайт. Браузер вроде как отправляет
> данные, но в сеть ничего не уходит, и браузер висит чего-
> то ожидая.

ситуация похожая, но у меня антивирус выключен, вообще ничего такого нет. я хочу попробовать перехватить функцию send у IE и посмотреть пытается ли он отправить этот пакет недостающий. Если отправляет, установить прокси-сервер и смотреть что через него прошло.


> В IE есть ограничение на количество посылаемых через XMLHTTPRequest
> запросов. Т.е если их относительно много посылать с какого
> то момента все перестает работать. Потом прочухивается и
> потом опять перестает. Есть какие то обходные пути для этого
> и даже библиотеки какие то. Сам сталкивался с этим.

Да вроде у меня и не много запросов. Удивительно что на том же сайте тот же ие работает отлично, если сайт находится на виртуальной машине. А на реальной - этот досадный глюк.


 
Дмитрий С ©   (2012-05-25 02:32) [18]

Быть может как-то и с ограничением на максимальное количество соединений связано. IE9 в моем случае без всякого стыда по 7-10 подключений одновременно держит и тот мой запрос, что раз в секунду выполняется по очереди пускает по всем соединениям. Вообще странно зачем он так.


 
Омлет ©   (2012-05-25 08:32) [19]


> Дмитрий С ©

Проверять readyState запроса надо в обработчике onreadystatechange. Зачем таймер городить?


 
han_malign   (2012-05-25 11:32) [20]


> if (isok || istimeout) {
>    clearInterval(int);
>    int = false;
>    if (isok) {
>     status=req.status;
>    }
>    else if (istimeout) {
>     req.abort();
>     status="timeout";
>    }
>             var text;
>             if (status != 200)
>                 console.log(status);

- для начала, хотя бы
   status="timeout (" + req.status + ")";
   req.abort();
   //status="timeout";

- нехрен реальную информацию маскировать...


> var req = new XMLHttpRequest();

- а вот с такими конструкциями надо очень и очень аккуратно, т.к. здесь это объявление глобальной  переменной содержащей ссылку ActiveX объект(IE only), которая отнюдь не освобождается после выхода...
А с подсчетом ссылок в IE - не все благополучно, так что помимо нескольких одновременных сессий, можно и утечку огрести...

И после подсчета количества new у меня зародилось подозрение - что keep-alive там никаким боком не уперся...


 
Омлет ©   (2012-05-25 11:39) [21]

Вот, кстати, есть даже одноменный сайт http://xmlhttprequest.ru/ - прямо на главной странице есть примеры, как надо правильно задавать таймаут и использовать onreadystatechange.


 
Дмитрий С ©   (2012-05-25 12:12) [22]


> Проверять readyState запроса надо в обработчике onreadystatechange.
>  Зачем таймер городить?

Это с давних времен еще. Установка обработчика onreadystatechange приводила к утечкам памяти в IE, оттуда и пошло.


 
Дмитрий С ©   (2012-05-25 12:20) [23]


> И после подсчета количества new у меня зародилось подозрение
> - что keep-alive там никаким боком не уперся...

На странице ведь еще и картинки есть помимо этих запросов. По идеи KeepAlive для них. Не использовать keep-alive это решение, но вопрос то, почему не работает, остается.


> > var req = new XMLHttpRequest();

Не совсем понял. Почему глобальной?


> Омлет ©   (25.05.12 11:39) [21]

А вот Вика немного по-другому говорит http://ru.wikipedia.org/wiki/XMLHttpRequest и кому верить? Да и к вопросу это не относится, думаю.


 
Омлет ©   (2012-05-25 13:25) [24]


> А вот Вика немного по-другому говорит

Что именно она по-другому говорит? Там всё то же - через onreadystatechange.


 
Омлет ©   (2012-05-25 13:33) [25]


> Установка обработчика onreadystatechange приводила к утечкам
> памяти в IE, оттуда и пошло.

Т.е. вместо исправления утечки приделал костыли.


 
han_malign   (2012-05-25 14:16) [26]


> Не совсем понял. Почему глобальной?

- наврал я, это если без var, то получится свойство глобального объекта... - а так вроде путем должно быть...

Но вот двойной new - меня все таки смущает...


 
Евгений Кузнецов   (2012-05-25 16:25) [27]


> Но вот двойной new - меня все таки смущает...

Меня тоже смущает :)


> Что именно она по-другому говорит? Там всё то же - через
> onreadystatechange.

Какое это имеет значение к вопросу?


 
Омлет ©   (2012-05-25 16:31) [28]


> Какое это имеет значение к вопросу?

Есть вероятность, что ошибка в говнокоде.


 
Дмитрий С ©   (2012-05-25 19:07) [29]


> Есть вероятность, что ошибка в говнокоде.

Есть вероятность, что вы даже тему не прочли.


 
знайка   (2012-05-26 00:55) [30]

postdata надо ловить и смотреть (дебажить)


 
Дмитрий С ©   (2012-05-26 02:01) [31]


> знайка   (26.05.12 00:55) [30]
>
> postdata надо ловить и смотреть (дебажить)

postdata не появляется даже в сниффере, в этом то и проблема. То ли IE не отправляет (хотя правильно указывает заголовок Content-Length), то ли какая-то програмка сбрасывает этот IP пакет с телом запроса. Вобщем полнейшая непонятка.


 
знайка   (2012-05-26 02:21) [32]

А Content-Type при этом?

Content-Type: application/x-www-form-urlencoded; charset=utf-8, допишите, попробовать...



Страницы: 1 вся ветка

Текущий архив: 2013.03.22;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.049 c
15-1345037851
Artem
2012-08-15 17:37
2013.03.22
Посоветуйте фоторесайзер любых размеров.


15-1340444273
AlexDn
2012-06-23 13:37
2013.03.22
Проверьте чертежи..!


15-1336595403
Юрий
2012-05-10 00:30
2013.03.22
С днем рождения ! 10 мая 2012 четверг


15-1340314077
ZV
2012-06-22 01:27
2013.03.22
Компонент Async32 не работает в С++


2-1345811633
Егорка
2012-08-24 16:33
2013.03.22
Безопасен ли вызов в DllMain такой функции