Advertisement
Guest User

Untitled

a guest
Sep 16th, 2011
15,136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 4.18 KB | None | 0 0
  1. <?php
  2.  
  3. /**
  4.  * Класс, реализующий функционал polling-сервера
  5.  */
  6. class Polling
  7. {
  8.     /**
  9.      * Обработчики событий
  10.      * @var array
  11.      */
  12.     protected $_handlers = array();
  13.  
  14.     /**
  15.      * Генерация события
  16.      * @param tstring $event Имя события
  17.      * @param array $data Параметры события
  18.      */
  19.     public function push($event, $data = null)
  20.     {
  21.         /**
  22.          *  В памяти первые восемь байт содержат длину данных, сами данные хранятся как сериализованный массив вида
  23.          * array('evant_name1' => event_time, ..., '_updated' => event_time)
  24.          * где event_time - это время возникновения последнего события
  25.          * _updated - специальное поле, где хранится время возникновения последнего события
  26.          */
  27.         $shmid = shmop_open(ftok(__FILE__, 'e'), 'c', 0644, 1024);
  28.         if ($shmid) {
  29.             $storageLength = (int) shmop_read($shmid, 0, 8);
  30.             $storage = array();
  31.             if ($storageLength) {
  32.                 $storage = unserialize(strval(shmop_read($shmid, 8, (int) $storageLength)));
  33.             }
  34.             $storage[$event] = array('time' => time(), 'data' => $data);
  35.             $storage['_updated'] = time();
  36.             $storageLength =  strlen(serialize($storage));
  37.             shmop_write($shmid,  (int) $storageLength, 0);
  38.             shmop_write($shmid, serialize($storage), 8);
  39.             shmop_close($shmid);
  40.         }
  41.     }
  42.  
  43.     /**
  44.      * "Слежение"за возникновением событий. Время работы зависит от опции msx_execution_time
  45.      * @param int $lastQueryTime Время завершения последнего запроса на "прослушивание".
  46.      * Используется для того ,чтобы при медленном соединении не терялись события, возникшие
  47.      * между запросами. Если не указан, то события отслеживаются с момента начала запроса
  48.      * @return array Массив с результатами выполнения обработчиков для возникших событий
  49.      */
  50.     public function listen($lastQueryTime = null)
  51.     {
  52.         $lastQueryTime = ($lastQueryTime) ?: time();
  53.         $endTime = time() + (int) ini_get('max_execution_time') -1;
  54.         $shmid = shmop_open(ftok(__FILE__, 'e'), 'a', 0, 0);
  55.         $result = array();
  56.         if ($shmid) {
  57.             while (time() < $endTime) {
  58.                 sleep(1);
  59.                 $storageLength = (int) shmop_read($shmid, 0, 8);
  60.                 $storage= unserialize(strval(shmop_read($shmid, 8, (int) $storageLength)));
  61.                 if ($storage['_updated'] > $lastQueryTime) {
  62.                     unset($storage['_updated']);
  63.                     asort($storage);
  64.                     /**
  65.                      * Обход и выполнение зарегистрированных обработчиков событий
  66.                      */
  67.                     foreach ($storage as $event => $data) {
  68.                         if (substr($event, 0, 1) != '_' && $data['time'] > $lastQueryTime) {
  69.                             $ret =$this->_runHandler($event, $data['data']);
  70.                             if ($ret) {
  71.                                 $result[$event] = $ret;
  72.                             }
  73.                         }
  74.                     }
  75.                     // При возникновении события завершаем запрос и отправляем данные клиенту
  76.                     break;
  77.                 }
  78.             }
  79.             shmop_close($shmid);
  80.         }
  81.         return $result;
  82.     }
  83.  
  84.     /**
  85.      * Регистрация события и назначение обработчика. Поддерживается по одному обработчику на событие
  86.      * @param string $event Имя события
  87.      * @param callback $callback Функция-обработчик
  88.      */
  89.     public function registerEvent($event, $callback)
  90.     {
  91.         $this->_handlers[$event] = $callback;
  92.     }
  93.  
  94.     /**
  95.      * Запуск обработчика возникшего события
  96.      * @param string $keyИмя события
  97.      * @param array $data Параметры возникшего события
  98.      * @return mixed
  99.      */
  100.     protected function _runHandler($key, $data = array())
  101.     {
  102.         if (!empty($this->_handlers[$key])) {
  103.             return call_user_func_array($this->_handlers[$key], array($data));
  104.         }
  105.     }
  106. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement