Форум: "Прочее";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
ВнизКак правильно задать вопрос... Найти похожие ветки
← →
Дмитрий С © (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;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.054 c