2013-05-22 4 views
2

Интересует вопрос - как правильно остановить цикл while во сне. Тот факт, что я внедрил «длинный опрос», чтобы быстро обновлять информацию на сайте (предупреждение, другая информация).Остановка цикла while php

СУТЬ SCRIPT

1. Мы будем посылать GET-запрос на PHP-страницу, в которой скрипт находится.

2. Сценарий запускает цикл , а.

3. В этой серии там условия и сна (1) в конце, который приостанавливает выполнение цикла.

- если цикл работает более секунд - остановить выполнение цикла, соответственно, и сценарий.

- Если на вашем сайте есть новая информация, скажите «alert» - выведите результаты для пользователя и остановите цикл.

ПРОБЛЕМА Если пользователь закрывает окно браузера, или перезагружает страницу - новый запрос выполняется по сценарию, который начнется цикл снова. Но в этом случае предыдущее выполнение цикла в то время как не остановится, пока в нем не будет работать хотя бы одно условие. Если пользователь отправляет много запросов на страницу - память сервера начинает загружаться, и в результате все висит до тех пор, пока все пока не остановят выполнение.

ВОПРОС Как остановить цикл и сценарий в целом, при запуске перезагрузке страницы или клиент? Пока я делал следующее. Когда вы запускаете сценарий, который мы генерируем, получаем случайное число, присвоенное переменной, и то же самое с сеансом. Дальше внутри страны, выполняя условие, в котором переменная должна быть значением сеанса. Если false - остановите цикл. Если мы запустим скрипт на новом - значение изменений сеанса и, соответственно, вся предыдущая производительность при остановке. Могу ли я использовать эту опцию? И насколько это безопасно?

update.php

// Initialize the user's session 
$session = Session::instance(); 

     $rand = rand(); 
     $session->set('user_update_key', $rand); 
     $key = $rand; 

     $limit = 20; 
     $seconds = 0; 

     set_time_limit($limit + 1); 

     while (TRUE) { 
      if (Session::instance()->get('user_update_key') == $key) { 

       if (there are updates. if there is - output) { 
        echo 'update information'; 
        flush(); 
        exit; 
       } 
       if ($seconds == $limit) { // complete the loop at the expiration of the time. 
        echo 'Close'; 
        flush(); 
        exit; 
       } 
       $seconds++; 
      } else { 
       unset($session, $rand, $key, $notice, $mysession, $last_notice, $limit, $notise_return, $seconds); 
       flush(); 
       exit; 
      } 
      session_write_close(); 
      sleep(1); 
      session_start(); 

}

+0

'while (TRUE)' <- Уверен, что вам это не нужно, не так ли? –

+0

Вы можете использовать continue; ключевое слово для завершения цикла цикла. – Ali

+0

Вам действительно нужно session_write_close();/session_start(); ? Как инициируется процесс обновления, можно ли просто установить тайм-аут в 30 секунд? – Adder

ответ

0

Ваше состояние в то время как это неизменное, в то время как на практике это не так. Функция сна() возвращает 0, если успешно, поэтому, если вы перепишите а условие реакции на изменение возвращаемого значения сна(), то он может работать как задумано, см: http://php.net/manual/en/function.sleep.php

С резьбой и другие функции всегда важно знать, на какой ОС вы работаете. У меня Ubuntu, и он реагирует иначе, чем указано в документации.

function interruptedSleep(){ 
    $cond = true; 
    while($cond){ 
    $i = sleep(10); 
    if($i == 0){ 
    $cond = false; 
    } 
    } 
} 

При прерывании сна, закрыв браузер будет функция сна возврата 0 и цикл в тот же время прерываются, и программа будет Continu непосредственно после времени. Это исключение не будет.

+0

Можете ли вы привести пример кода? – qulery

+0

Установите, как вы сказали. Все время отображает false. :( В этом случае страница открыта – qulery

1

Следует помнить, что PHP и Apache вообще не предназначены для длительного опроса. Я не знаю, как это происходит, когда вы используете nginx, но несколько месяцев назад мне приходилось выполнять долгое задание на Apache. Все выглядело хорошо, пока мы не пошли на производство. Оказывается, ограничения Apache не позволяют вам поддерживать длительные соединения.

Сервер повесился и отказался принимать любые новые запросы, разрешив примерно 20 пользователям войти в систему и открыть 3-4 карты веб-страницы. Существуют также ограничения браузеров, которые препятствуют поддержанию слишком большого количества HTTP-соединений на одном хосте. Однако обходной путь - использование субдоменов.

Я попытался выяснить, как решить id, задал здесь несколько вопросов здесь, в StackOverflow, и все закончилось использованием node.js + socket.io, который является легким и с легкостью обрабатывает тысячи одновременных подключений.

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

+1

Спасибо за ответ! – qulery

0

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

+0

Вы хотите сказать, что это будет создано для каждого пользователя cronjob, который работает в фоновом режиме. Запросы ajax были сделаны для него долго? – qulery

+0

Это означает, что у вас есть один cronjob, который работает в фоновом режиме, а только для отправки электронной почты. У вас все еще есть скрипт PHP, который захватывает все записи из базы данных, которые необходимо отправить, и затем отправляет их. На стороне веб-сайта/приложения ajax запускается каждые X секунд, чтобы проверить, есть ли какие-либо предупреждения из базы данных, которые ему нужно показать, если есть предупреждение, которое оно всплывает или делает то, что вы хотите. – NCoder

+0

Вы можете быть уведомляется мгновенно с использованием этой технологии? – qulery

Смежные вопросы