Зависание винды при использовании динамической смены рисунка JS + PHP

mav-im

Новичок
Зависание винды при использовании динамической смены рисунка JS + PHP

Итак, есть задача: обновление картинки на страничке без обновления самой странички.
Решается довольно просто - совместное использование PHP и JavaScript.

Для отладки создал два файла: "dynamicImage.php" и "getImg.php".
Первый файл делает саму страничку. Листинг следующий:
PHP:
<html>
<head>
  <meta http-equiv="Content-Type" content = "text/html charset=windows-1251">
  <title>Часики тик-так</title>
  
  <script language="JavaScript" type="text/javascript">
  var enable_upd = true;   //Контроль запуска/остановки
  var timerID = Null;      //Номер таймера
  function JSClock()
  {
    if (enable_upd)
    {
      var img_name = new Date();     //берем текущую дату и время
      img_name = img_name.getTime(); //преобразуем в формат миллисекунд
      document.clockForm.myIMG.src = "getImg.php?"+img_name;  //смена рисунка
      timerID = setTimeout("JSClock()", 1000);                //установка таймера
    }
  }
  </script>

</head>

<body>

<form name="clockForm">

<h2>Пример динамической замены рисунка без обновления страницы</h2>
Отображаем дату и время загрузки страницы<br>
(проверка того, что страница при смене рисунка не перезагружается заново):
<br><br>
<?php
  echo date("H:i:s d M Y");
?>
<br><br>
<IMG ID=myIMG src="getImg.php">
<br>
<input type="button" value="Запуск часиков" 
       onclick="enable_upd = true; JSClock();">

<input type="button" value="Остановка" 
       onclick="enable_upd = false;">

</form>

</body>
</html>
На страничке после загрузки имеется рисунок с текущим временем на нем и две кнопки
("Запуск часиков" и "Остановка"). После нажатия кнопки запуска время на рисунке
изменяется с интервалом 1 сек. (устанавливается в функции setTimeout).

Второй файл "getImg.php" генерит рисунок, который с помощью функции JSClock (из
первого файла) заменяет имеющийся рисунок в браузере.
На всякий случай приведу и его листинг:
PHP:
<?php
  /*Данный файл генерит рисунок*/

  $img_height = 100;             //Высота
  $img_width = 265;              //Ширина
  $f_font = "ARIAL.ttf";         //Шрифт True Type
  $f_size = 28;                  //Размер Шрифта True Type для названия

  //Создаем переменную картинки
  $im = imageCreate($img_width, $img_height);
  $background_color = imageColorAllocate($im, 230, 230, 230);
  $blue =  imageColorAllocate($im, 0, 0, 255);

  // Рамка
  imageRectangle($im, 0,0,$img_width-1, $img_height-1, $blue);
  imageRectangle($im, 10,10,$img_width-11, $img_height-11, $blue);

  $s = iconv("windows-1251","UTF-8",date("H:i:s")); //Время
  $px = ($img_width - (strlen($s)*$f_size/1.5))/2;
  $py = ($img_height + $f_size)/2;
  imageTTFtext($im, $f_size, 0, $px, $py, $blue, $f_font, $s);

  header("Cache-Control: no-cache");     //без кэша
  Header("Content-type: image/png");     //тип файла
  imagePng($im);                         //Выводим
  imageDestroy($im);                     //Разрушение переменной
?>
Так вот, данные файлы работают как надо, но есть одно НО.
Через определенное кол-во минут (при текущем интервале вызова функции JSClock) браузер
IE виснет и весь виндоус также. При этом диспетчер задач показывает полную загрузку
проца 100% и 99% из них приходится на процесс Apache.exe.

При итервале замены рисунка 1 сек. - зависание происходит примерно через 20 минут
работы часиков.
Для ускорения процесса зависания можно интевал уменьшить до 100 мс, тогда где-то через
1 минуту все висит.
Анализируя приведенный код, я не могу найти ошибку. Так что у меня вопрос ко всем кодерам - В чем может быть дело?:confused:

Apache/2.0.53 и PHP/5.0.4. Настройки менял только в файле httpd.conf: заремовал
строчку AddDefaultCharset ISO-8859-1, чтоб нормально чарсет менять.
 

mav-im

Новичок
Спасибо за такой ответ, конечно, но то что у меня под ником написано "новичок" вовсе не означает, что я ламер. Это означает лишь то, что я новичок на данном форуме.

Программирую давненько, но вот с PHP сравнительно недавно, если сможешь еще раз взглянуть на приведенный код, то поймешь, что установка enable_upd=false в том месте является глупостью, т.к. такой код работать не будет.

Поясню. Функция setTimeout("выражение", time) устанавливает единоразовый таймер (который сработает один раз) на выполнение определенного выражения. В моем случае исполняемым выражением является вызов функции JSClock, но не из самой себя, как может показаться, а из таймера (можно назвать его отдельным объектом).

Как можно видеть в моей функции происходит проверка переменной enable_upd и если true, то можно сменить рисунок и установить новый таймер. Таким образом после нажатия кнопки "запуск часиков" смена рисунка будет происходить автоматически каждую секунду. Кто не понял, читайте материал по ООП (объектно-ориент. прогр.).

При нажатии на кнопку "остановка" переменной enable_upd будет присвоено значение false. Но таймер то уже установлен (объект уже включили), следовательно вызов функции JSClock все-таки произойдет, но смены рисунка уже не будет (см. условие) и также НЕ будет установлен новый таймер.

Вот и все, именно поэтому данный код является примитивным, в котором не содержится ошибки.

При этом Apache работает практически не нагружая процессор, утечки памяти также не замечено, но примерно через 20 минут все вдруг ни с того ни с сего виснет, это происходит мгновенно, т.е. есть подозрения, что срабатывает какое-то ограничение именно в настройках Апачи (к примеру максимальное количество запросов от одного устойчивого соединения или что-нить в этом роде), но это ограничение не может остановить КЛИЕНТСКИЙ скрипт JS, который в свою очередь опять таки пытается отправить запрос на сервер для формирования нового рисунка, что по моему мнению может привести к зависанию Апачи.

Я думаю, что заинтересованным в скриптах такого рода лицам можно попробовать создать приведенные мной два файла (они приведены полностью) и протестить у себя дома.

Так вот вопрос звучит так: Какие настройки Апачи можете посоветовать для того, чтобы можно было бесконечно долго и бесконечно много запрашивать у сервера чего-нить, в частном случае подгружать динамически создаваемые рисунки? Во как.

to Линка: спасибо за попытку, хоть и не в том направлении!
 

ksnk

прохожий
Не воспроизводится на Denver+IE 6.0.0.2... Нельзя ли уточнить стендовую конфигурацию?
По смутным симптомам - Apache не успевает вывести одну картинку, как прилетает запрос на следующую. Но это возможно только на ОЧЕНЬ загруженной машине...

Линка
Это не прогрессия. Чтобы завалится от этого надо бы бешено нажимать на кнопку "Запуск часиков"... При этом глючил бы не Apache, а IE
Ну, а чтобы не заваливаться уже от этого, достаточно переписать примерно так
Код:
...
 <script language="JavaScript" type="text/javascript">
  var timerID = Null;      //Номер таймера
  function JSClock()
  {
      var img_name = new Date();     //берем текущую дату и время
      img_name = img_name.getTime(); //преобразуем в формат миллисекунд
      document.clockForm.myIMG.src = "getImg.php?"+img_name;  //смена рисунка
      if(!timerID) timerID= setInterval("JSClock()", 1000);                //установка таймера
  }
  </script>
...

<input type="button" value="Запуск часиков" 
       onclick="JSClock();">

<input type="button" value="Остановка" 
       onclick="if(timerID) {clearInterval(timerID);timerID=null};">
 

mav-im

Новичок
ksnk
Твой код работает практически также (имею ввиду, что выполняет те же задачи), потому что, как я понял функция setInterval после определенного интервала вызывает выражение (в данном случае) и при этом сбрысывает timerID в Null. Либо по другому - данная функция выставляет интервал, через который будет происходить обработка выражения, причем не одноразово, а много раз, т.е. условие на (if !timerID) имеет значение только при нажатии кнопки "Запуск часиков", когда timerID стоит в Null.

В любом случае (просто не нашел описания функции setInterval) сути это практически не меняет.

Попробовал, зависание также происходит. У меня возникла идея - на время отладки убрать все клиентские скрипты и оставить чистый PHP, чтотбы проверить только работу Apache. Изменил страничку, теперь код такой:
PHP:
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<meta http-equiv="Refresh" CONTENT="1">
<!-- no cache headers -->
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="no-cache">
<meta http-equiv="Expires" content="-1">
<meta http-equiv="Cache-Control" content="no-cache">
<!-- end no cache headers -->
<title>БКН</title>
</head>

<body>
<?php
  /*Данный файл генерит рисунок*/

  $img_height = 100;             //Высота
  $img_width = 265;              //Ширина
  $f_font = "ARIAL.ttf";         //Шрифт True Type
  $f_size = 28;                  //Размер Шрифта True Type для названия

  //Создаем переменную картинки
  $im = imageCreate($img_width, $img_height);
  $background_color = imageColorAllocate($im, 230, 230, 230);
  $blue =  imageColorAllocate($im, 0, 0, 255);

  // Рамка
  imageRectangle($im, 0,0,$img_width-1, $img_height-1, $blue);
  imageRectangle($im, 10,10,$img_width-11, $img_height-11, $blue);

  $s = iconv("windows-1251","UTF-8",date("H:i:s")); //Время
  $px = ($img_width - (strlen($s)*$f_size/1.5))/2;
  $py = ($img_height + $f_size)/2;
  imageTTFtext($im, $f_size, 0, $px, $py, $blue, $f_font, $s);

  $img_fname = "imgs/val_cur_out.png";
  imagePng($im, $img_fname);                         //Выводим
  imageDestroy($im);              //Разрушение переменной
?>

<img src="imgs/val_cur_out.png?<?php echo time();?>"> <BR>
</body>

</html>
Теперь файл один. Данная страничка будет автоматически обновляться с интервалом в 1 сек. При этом каждый раз будет формироваться рисунок с текущим временем.

Запускаем данный файл - :( то же самое, ТО ЕСТЬ дело не в IE, а именно в Apache.

По смутным симптомам - Apache не успевает вывести одну картинку, как прилетает запрос на следующую. Но это возможно только на ОЧЕНЬ загруженной машине...
Да симптомы то такие, но с другой стороны машина вообще ничем, кроме Apache, не загружена да и рисунок не огромный, то есть время выполнения скрипта должно бытьт явно меньше 1 сек., что также можно видеть при нормальной работе Apache (страница сменяется мгновенно).

По конфигурации: пакет XAMPP-win32-1.4.13 три в одном MySQL+PHP(5.0.4)+Apache(2.0.53).
IE 6.0.2900.2180 - XP sp2 + Обновления.

Поэтому грешу на настройки Apache (в файле httpd.conf).
 

ksnk

прохожий
Мой код отличается от твоего только тем, что не использует переменную enable_upd и не выставляет каждую секунду setTimer, а в остальном, конечно, делает то-же самое...

Можно подойти к делу как настоящие программисты :)
Выкидывать из текста куски, до тех пор пока эффект не пропадет, затем выяснить - на каком операторе глючит.
К примеру - если оставить только обновление с выводом картинки (без генерации GD ) работать будет? А если повыкидывать некоторые операторы в генераторе картинки... ets...
 

mav-im

Новичок
Ну, я как можно видеть уже начал этим заниматься, пока 0, завтра попробую без генерации картинки, просто загрузку, если не получится, то тогда думаю будет понятно, что дело точно в Apache.

-~{}~ 13.03.07 23:46:

Спасибо, всем за помощь. Приведенный мною в самом начале скрипт отлично работает сам по себе.

Пробовал на работе - в течении 2-х часов тестил, потом надоело.

Дома по каким-то непонятным мне причинам Apache конфликтовал с программой SlyControl2 . Если у кого есть соображения по этому поводу, готов выслушать.

После отключения данной проги все заработало на Ура.

-~{}~ 15.03.07 04:51:

Нашел еще один КОСЯЧОК.
Оказалось, что конфликт со SlyControl это полбеды.
Главным виновником зависания был nView Desktop Manager. После его отключения косяков не замечено:)
 
Сверху