Форумы портала PHP.SU » PHP » Пользовательские функции » Обработчик кеширования

Страниц (1): [1]
 

1. EuGen - 21 Февраля, 2013 - 14:00:04 - перейти к сообщению
Приветствую, как и обещал, привожу пример кеша на PHP. Сделано это не как попытка создания быстрого кеша, который может быть реально использован по назначению (то есть, ускорению приложения), поскольку быстрота исполнения интерпретируемого кода оставляет желать лучшего.
Однако же концепция, которую я вкладываю в понятие "кеш", должна быть понятна на данном примере. Кроме того, для изучения может быть полезен просмотр кода - в плане работы с сетью через сокеты. Пример достаточно прост, не имеет множества вещей, которые были бы полезны (полной обработки ошибок, или, например, попыток повторных соединений), но, так как в любом случае интерес этот код может представлять лишь академический, а не практический, я не углублялся в такие детали.

Как это работает. Очень просто - существует кеш-сервер, который слушает входящие соединения на предопределенном порту. Он обрабатывает клиентов, которые с ним соединяются, и, если те шлют команды по протоколу, который он понимает, делает всю полезную работу - хранит кеш, предоставляет значение по ключу и т.п. Код сервера:
PHP:
скопировать код в буфер обмена
  1. class Cache_Server
  2. {
  3.     const PARSER_RAW_SECTION_COMMAND    = 'raw_command';
  4.     const PARSER_RAW_SECTION_DATA       = 'raw_data';
  5.    
  6.     const HANDLER_COMMAND_COMMON_PREFIX = '_hook_';
  7.     const HANDLER_COMMAND_SET_KEY       = 'key';
  8.     const HANDLER_COMMAND_SET_DATA      = 'data';
  9.     const HANDLER_COMMAND_SET_SUCCESS   = 1;
  10.     const HANDLER_COMMAND_SET_FAILURE   = 0;
  11.    
  12.     const SOCKET_BLOCK_READ_SIZE        = 64;
  13.     const SOCKET_TERMINATE_BYTE         = "\0";
  14.    
  15.     const ERROR_SERVER_SETUP_MESSAGE    = "Could not setup server socket";
  16.     const ERROR_SERVER_SETUP_CODE       = 2;
  17.    
  18.     protected $_sAddress                = '127.0.0.1';
  19.     protected $_sPort                   = '23540';
  20.     protected $_rgClients               = array();
  21.     protected $_rgErrors                = array();
  22.     private   $__rgCache                = array();
  23.     private   $__rSocket                = null;
  24.    
  25.     public function __construct($sHost=null, $sPort=null)
  26.     {
  27.         if(isset($sHost)&&isset($sPort))
  28.         {          
  29.             $this->_sAddress= $sHost;
  30.             $this->_sPort   = $sPort;
  31.         }
  32.     }
  33.    
  34.     public function runServer()
  35.     {
  36.         if(!$this->__setup_socket())
  37.         {
  38.             $this->setError(self::ERROR_SERVER_SETUP_CODE, self::ERROR_SERVER_SETUP_MESSAGE);
  39.             return false;
  40.         }
  41.         while(true)
  42.         {
  43.             $this->_check_clients();
  44.             $this->_listen_clients();
  45.         }
  46.     }
  47.     //errors functions:
  48.     public function getLastError()
  49.     {
  50.         return $this->_rgErrors[count($this->_rgErrors)-1];
  51.     }
  52.    
  53.     public function setError($iCode, $sMessage)
  54.     {
  55.         $this->_rgErrors[]  = array($iCode=>$sMessage);
  56.     }
  57.     //cache functions:
  58.     public function getKey($mClient, $mKey)
  59.     {
  60.         $sKey   = $this->__generate_key_hash($mClient, $mKey);
  61.         return array_key_exists($sKey, $this->__rgCache)?$this->__rgCache[$sKey]:null;
  62.     }
  63.  
  64.     public function setKey($mClient, $mKey, $mValue)
  65.     {
  66.         if(!isset($mValue))
  67.         {
  68.             unset($this->__rgCache[$this->__generate_key_hash($mClient, $mKey)]);
  69.         }
  70.         else
  71.         {
  72.             $this->__rgCache[$this->__generate_key_hash($mClient, $mKey)]=$mValue;
  73.         }
  74.     }
  75.     //clients functions:
  76.     protected function _check_clients()
  77.     {
  78.         if(($rNewc = @socket_accept($this->__rSocket)) !== false)
  79.         {
  80.             socket_set_nonblock($rNewc);
  81.             $this->_rgClients[] = $rNewc;
  82.         }
  83.     }
  84.    
  85.     protected function _listen_clients($bCheckAlive=false)
  86.     {
  87.         foreach($this->_rgClients as $iIndex => $rClient)
  88.         {
  89.             if($sData = $this->__get_socket_data($rClient))
  90.             {
  91.                 if($rgCommand = $this->__parse_raw_command($sData))
  92.                 {
  93.                     $this->_execute_command($iIndex, $rgCommand[self::PARSER_RAW_SECTION_COMMAND], $rgCommand[self::PARSER_RAW_SECTION_DATA]);
  94.                 }
  95.             }
  96.         }
  97.     }
  98.     //command handle functions:
  99.     protected function _execute_command($mClient, $sCommand, $mParameters)
  100.     {
  101.         //need to use prefix, so call will be more safe:
  102.         if(method_exists($this, $sCommand=self::HANDLER_COMMAND_COMMON_PREFIX.$sCommand))
  103.         {
  104.             $this->$sCommand($mClient, $mParameters);
  105.         }
  106.     }
  107.    
  108.     protected function _hook_get($mClient, $mParameters)
  109.     {
  110.         $mClient    = is_resource($mClient)?$mClient:$this->_rgClients[$mClient];
  111.         $this->__send_socket_data($mClient, $this->getKey($mClient, (string)$mParameters));
  112.     }
  113.    
  114.     protected function _hook_set($mClient, $mParameters)
  115.     {
  116.         $mClient    = is_resource($mClient)?$mClient:$this->_rgClients[$mClient];
  117.         if($rgParameters = @unserialize($mParameters))
  118.         {
  119.             if(array_key_exists(self::HANDLER_COMMAND_SET_KEY, $rgParameters))
  120.             {
  121.                 $sKey = $rgParameters[self::HANDLER_COMMAND_SET_KEY];
  122.                 $this->setKey($mClient, $sKey, null);
  123.                 if(array_key_exists(self::HANDLER_COMMAND_SET_DATA, $rgParameters))
  124.                 {
  125.                     $this->setKey($mClient, $sKey, $rgParameters[self::HANDLER_COMMAND_SET_DATA]);                    
  126.                 }
  127.                 $this->__send_socket_data($mClient, self::HANDLER_COMMAND_SET_SUCCESS);
  128.                 return true;
  129.             }
  130.         }
  131.         $this->__send_socket_data($mClient, self::HANDLER_COMMAND_SET_FAILURE);
  132.         return false;
  133.     }
  134.    
  135.     private function __generate_key_hash($mClient, $mKey)
  136.     {
  137.         return md5($mClient."\n\n".$mKey);
  138.     }
  139.     //socket functions:
  140.     private function __setup_socket()
  141.     {
  142.         $this->__rSocket    = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
  143.         if(!@socket_bind($this->__rSocket,$this->_sAddress,$this->_sPort))
  144.         {
  145.             unset($this->__rSocket);
  146.             return false;
  147.         }
  148.         socket_listen($this->__rSocket);
  149.         socket_set_nonblock($this->__rSocket);
  150.         return true;
  151.     }
  152.    
  153.     private function __send_socket_data($rSocket, $sData)
  154.     {
  155.         return socket_write($rSocket, $sData.self::SOCKET_TERMINATE_BYTE);
  156.     }
  157.    
  158.     private function __get_socket_data($rSocket)
  159.     {
  160.         $sResult = false;
  161.         while($sBuffer = @socket_read($rSocket, self::SOCKET_BLOCK_READ_SIZE))
  162.         {
  163.             $sResult.=$sBuffer;
  164.         }
  165.         return $sResult===false?null:$sResult;
  166.     }
  167.    
  168.     private function __parse_raw_command($sData)
  169.     {
  170.         $mData  = @unserialize($sData);
  171.         if(is_array($mData) && array_key_exists(self::PARSER_RAW_SECTION_COMMAND, $mData))
  172.         {
  173.             return $mData;
  174.         }
  175.         return null;
  176.     }
  177. }

и, собственно, пример использования:
PHP:
скопировать код в буфер обмена
  1. $rServer = new Cache_Server();
  2. $rServer->runServer();

- на этом функции сервера завершаются. То есть он не делает ничего "активного", лишь являясь хранилищем данных и принимая запросы на их изменение/предоставление.
Теперь клиент. Здесь тоже все предельно ясно - реализован синглтон, который пытается соединиться с сервером и умеющий работать с ним по предопределенному протоколу. Этот синглтон не закрывает сокет каждый раз при обращении, что экономит сетевой оверхед. Это может быть важной деталью - если использующий клиента скрипт не предполагает поддерживаемых соединений, то, вероятно, такой подход не подойдет. Правда, это легко исправимо. Код клиента:
PHP:
скопировать код в буфер обмена
  1. class Cache_Client
  2. {
  3.     const PARSER_RAW_SECTION_COMMAND    = 'raw_command';
  4.     const PARSER_RAW_SECTION_DATA       = 'raw_data';
  5.    
  6.     const COMMAND_GET                   = 'get';
  7.     const COMMAND_SET                   = 'set';
  8.     const COMMAND_SET_KEY               = 'key';
  9.     const COMMAND_SET_DATA              = 'data';
  10.    
  11.     const SOCKET_TERMINATE_BYTE         = "\0";
  12.    
  13.     const ERROR_CLIENT_SETUP_MESSAGE    = "Could not setup client socket";
  14.     const ERROR_CLIENT_SETUP_CODE       = 1;
  15.    
  16.     protected $_sAddress                = '127.0.0.1';
  17.     protected $_sPort                   = '23540';
  18.     protected $__rSocket                = null;
  19.     protected $_rgErrors                = array();
  20.    
  21.     protected static $_rInstance        = null;
  22.    
  23.     private function __construct()
  24.     {
  25.        
  26.     }
  27.    
  28.     public function setServerAddress($sAddress, $sPort)
  29.     {
  30.         $this->_sAddress    = $sAddress;
  31.         $this->_sPort       = $sPort;
  32.         $this->__setup_socket();
  33.         return $this;
  34.     }
  35.    
  36.     public static function getInstance()
  37.     {
  38.         if(isset(self::$_rInstance))
  39.         {
  40.             return self::$_rInstance;
  41.         }
  42.         self::$_rInstance = new Cache_Client;
  43.         self::$_rInstance->__setup_socket();
  44.         return self::$_rInstance;
  45.     }
  46.    
  47.     public function getLastError()
  48.     {
  49.         return $this->_rgErrors[count($this->_rgErrors)-1];
  50.     }
  51.    
  52.     public function setError($iCode, $sMessage)
  53.     {
  54.         $this->_rgErrors[]  = array($iCode=>$sMessage);
  55.     }
  56.    
  57.     public function getKey($sKey)
  58.     {
  59.         $this->__send_socket_data($this->__rSocket, serialize(
  60.                 array(
  61.                     self::PARSER_RAW_SECTION_COMMAND=> self::COMMAND_GET,
  62.                     self::PARSER_RAW_SECTION_DATA   => $sKey
  63.                 )
  64.         ));
  65.         if($sData = @unserialize($this->__get_socket_data($this->__rSocket)))
  66.         {
  67.             return $sData;
  68.         }
  69.         return null;
  70.     }
  71.    
  72.     public function setKey($sKey, $mValue)
  73.     {
  74.         $this->__send_socket_data($this->__rSocket, serialize(
  75.                 array(
  76.                     self::PARSER_RAW_SECTION_COMMAND=> self::COMMAND_SET,
  77.                     self::PARSER_RAW_SECTION_DATA   => serialize(array(
  78.                         self::COMMAND_SET_KEY   => $sKey,
  79.                         self::COMMAND_SET_DATA  => serialize($mValue)
  80.                     ))
  81.                 )
  82.         ));
  83.         return (bool)$this->__get_socket_data($this->__rSocket);
  84.     }
  85.    
  86.     public function unsetKey($sKey)
  87.     {
  88.         $this->__send_socket_data($this->__rSocket, serialize(
  89.                 array(
  90.                     self::PARSER_RAW_SECTION_COMMAND=> self::COMMAND_SET,
  91.                     self::PARSER_RAW_SECTION_DATA   => serialize(array(
  92.                         self::COMMAND_SET_KEY   => $sKey
  93.                     ))
  94.                 )
  95.         ));
  96.         return (bool)$this->__get_socket_data($this->__rSocket);
  97.     }
  98.    
  99.     private function __setup_socket()
  100.     {
  101.         $this->__rSocket    = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
  102.         if(!@socket_connect($this->__rSocket, $this->_sAddress, $this->_sPort))
  103.         {
  104.             unset($this->__rSocket);
  105.             $this->setError(self::ERROR_CLIENT_SETUP_CODE, self::ERROR_CLIENT_SETUP_MESSAGE);
  106.             return false;
  107.         }
  108.         return true;
  109.     }
  110.    
  111.     private function __send_socket_data($rSocket, $sData)
  112.     {
  113.         if(!$rSocket)
  114.         {
  115.             return null;
  116.         }
  117.         return socket_write($rSocket, $sData);
  118.     }
  119.    
  120.     private function __get_socket_data($rSocket)
  121.     {
  122.         if(!$rSocket)
  123.         {
  124.             return null;
  125.         }
  126.         $sResult = false;
  127.         while(($sBuffer = @socket_read($rSocket, 1))!=self::SOCKET_TERMINATE_BYTE)
  128.         {
  129.             $sResult.=$sBuffer;
  130.         }
  131.         return $sResult===false?null:$sResult;
  132.     }
  133. }

и, опять же, пример использования:
PHP:
скопировать код в буфер обмена
  1. $rCache = Cache_Client::getInstance()->setServerAddress('127.0.0.1', '23540');
  2. var_dump($rCache->setKey('test', array(1,'foo', false)));
  3. var_dump($rCache->getKey('test'));
  4.  
  5. $rCacheIns = Cache_Client::getInstance();
  6.  
  7. var_dump($rCacheIns->unsetKey('test'));
  8. var_dump($rCacheIns->getKey('test'));

Пару слов о протоколе. Как это нетрудно заметить, данные, которые шлются между клиентом и сервером - обычный текст. Поэтому на помощь приходит функция serialize. Сериализуется команда, которая отправляется серверу, её параметры, а так же значение ключа, если оно передается. Клиент, соответственно, десериализует ответ при получении данных из кеша, а прочие же строки сервер отдает как есть (например,статус успешности операции установки ключа).
2. dubasua - 21 Февраля, 2013 - 16:26:32 - перейти к сообщению
EuGen пишет:
Код сервера:

Я так понял он запускается единожды? Допустим после старта самого сервера? И он не пускается с пользовательских скриптов.
А ему нужны какие нибудь права супер пользователя, я к тому что его реально запустить на недорогом покупном хостинге?
3. EuGen - 21 Февраля, 2013 - 16:36:10 - перейти к сообщению
Запускается 1 раз. Никаких прав не нужно, единственное, что нужно - это установленное расширение сокетов для PHP (но не уверен, что можно отыскать хостинг без него).
Но этот код - хоть и рабочий, все же является лишь прототипом, поскольку по-хорошему нужно делать обработку ошибок, сброс кеша на диск в случае непредвиденной остановки и т.п.
4. dubasua - 21 Февраля, 2013 - 16:46:16 - перейти к сообщению
Ну таки не плохо, но все же, я пока что не увидел разницы над тем что предложил DeepVarvar.
5. DeepVarvar - 21 Февраля, 2013 - 16:47:46 - перейти к сообщению
Хе-хе, интересная игрушка Закатив глазки
6. EuGen - 21 Февраля, 2013 - 16:48:06 - перейти к сообщению
Разница в том, что во-первых, ресурс полностью разделяемый (блокировки отсутствуют в принципе, так как каждый клиент имеет свой кеш), и во-вторых, не требует специфичного shm-расширения (а вот оно-то как раз, не так часто бывает).
7. DeepVarvar - 21 Февраля, 2013 - 16:48:48 - перейти к сообщению
dubasua пишет:
я пока что не увидел разницы над тем что предложил DeepVarvar.
EuGen сделал "копию" мемкеша, а я предложил хранить в оперативке напрямую без стороннего "сервера".
(Добавление)
Ну не суть. Суть в том какие задачи у dubasua Закатив глазки
8. EuGen - 21 Февраля, 2013 - 16:54:51 - перейти к сообщению
DeepVarvar пишет:
а я предложил хранить в оперативке напрямую без стороннего "сервера".

Это, кстати, порождает еще одно отличие - клиент может иметь намного меньше потребляемой памяти по сравнению с сервером (поскольку клиент может вообще не хранить данные, а только работать с ними, таким образом, количество памяти, требуемой клиенту, ограничится лишь размером, требуемым для обработки конкретного ключа (или набора ключей) из кеша)
Копия memcached - звучит громко, хотя бы потому, что все это написано на PHP. Но суть - да, та же.
9. dubasua - 21 Февраля, 2013 - 16:55:00 - перейти к сообщению
Хм,хм. Это к примеру если на одном хосте будут работать две одинаковые CMS, на которых работает пример DeepVarvar, то могут возникнуть парадоксы? А если будет пример EuGen, то кеш будет изолирован от каждой CMS?
10. EuGen - 21 Февраля, 2013 - 16:56:56 - перейти к сообщению
В случае с кешем, который привел в пример я, кеш-сервер вообще ничего не знает о том, кто его использует. Это могут быть CMS или CLI-скрипты или вообще даже не PHP-скрипты - разницы нет, лишь бы соблюдали протокол работы с сервером.
11. dubasua - 21 Февраля, 2013 - 17:02:27 - перейти к сообщению
EuGen пишет:
клиент может иметь намного меньше потребляемой памяти по сравнению с сервером
,
Я вот только начал въезжать А?!, клиент это мой хостинг, а сервер может быть совсем в другом месте(физически) на другом айпи???
12. EuGen - 21 Февраля, 2013 - 17:04:11 - перейти к сообщению
Именно так. Можете даже через WAN данные передавать. Правда, остается только посочувствовать той системе, быстродействие которой будет "улучшаться" подобным образом, поскольку скорость работы станет напрямую зависима от скорости передачи по сети и её надёжности.
13. dubasua - 21 Февраля, 2013 - 17:09:11 - перейти к сообщению
Дык родилась идея создать платный сервис!!! покупаем VPS и кешируем половину ru-нета Улыбка
(Добавление)
Тем более половина готового кода уже есть! ;)
14. EuGen - 21 Февраля, 2013 - 17:47:03 - перейти к сообщению
На трафике разоритесь. Кешировать половину рунета можно и в memcached. Никакой Америки здесь не открыто.
15. Shyt - 05 Января, 2014 - 14:46:12 - перейти к сообщению
p.s Если что не судите строго, первый раз вообще смотрю на это

так всё интересно, но я много чего не смог понять, не могли бы вы мне помочь разобраться в этом примере и посмотреть как я разобрался в нем, я прогнал всё что понял но не уверен конечно что прав и остались некоторые нюансы

PHP:
скопировать код в буфер обмена
  1.  
  2. // стадия 1
  3. class Cache_Server{
  4.         // 2.0 обрабатываються все переменные
  5.     const PARSER_RAW_SECTION_COMMAND    = 'raw_command';
  6.     const PARSER_RAW_SECTION_DATA       = 'raw_data';
  7.     const HANDLER_COMMAND_COMMON_PREFIX = '_hook_';
  8.     const HANDLER_COMMAND_SET_KEY       = 'key';
  9.     const HANDLER_COMMAND_SET_DATA      = 'data';
  10.     const HANDLER_COMMAND_SET_SUCCESS   = 1;
  11.     const HANDLER_COMMAND_SET_FAILURE   = 0;
  12.        
  13.     const SOCKET_BLOCK_READ_SIZE        = 64;
  14.     const SOCKET_TERMINATE_BYTE         = "\0";
  15.        
  16.     const ERROR_SERVER_SETUP_MESSAGE    = "Could not setup server socket";
  17.     const ERROR_SERVER_SETUP_CODE       = 2;
  18.        
  19.     protected $_sAddress                = '127.0.0.1';
  20.         protected $_sPort                   = '23540';
  21.     protected $_rgClients               = array();
  22.     protected $_rgErrors                = array();
  23.     private   $__rgCache                = array();
  24.     private   $__rSocket                = null;
  25.    
  26.         // 2.1 запускается автоматом конструктор и выполняется внос данных в переменные
  27.     public function __construct($sHost=null, $sPort=null){
  28.         if(isset($sHost)&&isset($sPort)){          
  29.             $this->_sAddress = $sHost;
  30.             $this->_sPort = $sPort;
  31.                         }
  32.         }
  33.        
  34.         // вот наша стадия 2.2
  35.     public function runServer(){
  36.                 //3. как понимаю сначало это, на проверку создания
  37.         if(!$this->__setup_socket()){
  38.             $this->setError(self::ERROR_SERVER_SETUP_CODE, self::ERROR_SERVER_SETUP_MESSAGE);// 4.1 это вроде типа если ошибки
  39.             return false;
  40.                         }
  41.         //4.2 это вроде цикла прослушивания  
  42.                 while(true){
  43.             $this->_check_clients();
  44.             $this->_listen_clients();
  45.             }
  46.         }
  47.                
  48.         //errors functions:
  49.     public function getLastError(){
  50.         return $this->_rgErrors[count($this->_rgErrors)-1];
  51.         }
  52.      
  53.         // стадия 4.1
  54.     public function setError($iCode, $sMessage){
  55.         $this->_rgErrors[] = array($iCode=>$sMessage);// занос в массив
  56.         }
  57.                
  58.                
  59.     // ненашел?
  60.         public function getKey($mClient, $mKey){
  61.         $sKey = $this->__generate_key_hash($mClient, $mKey);
  62.         return array_key_exists($sKey, $this->__rgCache)?$this->__rgCache[$sKey]:null;
  63.         }
  64.    
  65.         // ненашел?
  66.     public function setKey($mClient, $mKey, $mValue){
  67.         if(!isset($mValue)){
  68.             unset($this->__rgCache[$this->__generate_key_hash($mClient, $mKey)]);
  69.         }else{
  70.             $this->__rgCache[$this->__generate_key_hash($mClient, $mKey)]=$mValue;
  71.             }
  72.         }
  73.  
  74.                
  75.         //8. бесконечный цикл порверки данных
  76.     protected function _check_clients(){
  77.                 // ждем данных но только не от себя
  78.         if(($rNewc = @socket_accept($this->__rSocket)) !== false){
  79.             socket_set_nonblock($rNewc); // это типа вроде мы, но я не допер
  80.             $this->_rgClients[] = $rNewc; // не понял зачем себя вносить в массив?
  81.             }
  82.         }
  83.    
  84.         //9. работа с клиентами
  85.     protected function _listen_clients($bCheckAlive=false// не понял что значит?){
  86.         foreach($this->_rgClients as $iIndex => $rClient){ // тоже не догнал манипуляция с клиентами чтоли?
  87.             if($sData = $this->__get_socket_data($rClient)){ // 10. типа что то читаем или получаем
  88.                 if($rgCommand = $this->__parse_raw_command($sData)){ // 11. ну это вроде обработка чего получили
  89.                     $this->_execute_command($iIndex, $rgCommand[self::PARSER_RAW_SECTION_COMMAND], $rgCommand[self::PARSER_RAW_SECTION_DATA]);// 12. что то о безопастности
  90.                     }
  91.                 }
  92.             }
  93.         }
  94.                
  95.                
  96.     // стадия 12
  97.     protected function _execute_command($mClient, $sCommand, $mParameters){
  98.         if(method_exists($this, $sCommand=self::HANDLER_COMMAND_COMMON_PREFIX.$sCommand)){
  99.             $this->$sCommand($mClient, $mParameters);
  100.             }
  101.         }
  102.        
  103.         // ненашел?
  104.     protected function _hook_get($mClient, $mParameters){
  105.         $mClient  = is_resource($mClient)?$mClient:$this->_rgClients[$mClient];
  106.         $this->__send_socket_data($mClient, $this->getKey($mClient, (string)$mParameters));
  107.         }
  108.      
  109.         // ненашел?
  110.     protected function _hook_set($mClient, $mParameters){
  111.         $mClient = is_resource($mClient)?$mClient:$this->_rgClients[$mClient];
  112.         if($rgParameters = @unserialize($mParameters)){
  113.             if(array_key_exists(self::HANDLER_COMMAND_SET_KEY, $rgParameters)){
  114.                 $sKey = $rgParameters[self::HANDLER_COMMAND_SET_KEY];
  115.                 $this->setKey($mClient, $sKey, null);
  116.                 if(array_key_exists(self::HANDLER_COMMAND_SET_DATA, $rgParameters)){
  117.                     $this->setKey($mClient, $sKey, $rgParameters[self::HANDLER_COMMAND_SET_DATA]);                    
  118.                     }
  119.                 $this->__send_socket_data($mClient, self::HANDLER_COMMAND_SET_SUCCESS);
  120.                                 return true;
  121.                                 }
  122.                         }
  123.             $this->__send_socket_data($mClient, self::HANDLER_COMMAND_SET_FAILURE);
  124.             return false;
  125.         }
  126.        
  127.         // ненашел?
  128.     private function __generate_key_hash($mClient, $mKey){
  129.         return md5($mClient."\n\n".$mKey);
  130.         }
  131.                
  132.     //5. подготовка к подключению и создания сокета
  133.     private function __setup_socket(){
  134.         $this->__rSocket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
  135.         if(!@socket_bind($this->__rSocket,$this->_sAddress,$this->_sPort)){
  136.             unset($this->__rSocket);
  137.             return false;
  138.             }
  139.        
  140.                 socket_listen($this->__rSocket);// 6. прослушиваем подключение
  141.         socket_set_nonblock($this->__rSocket);// 7. не врубился но вроде постояная активность
  142.         return true;
  143.         }
  144.    
  145.         // ненашел?
  146.     private function __send_socket_data($rSocket, $sData){
  147.         return socket_write($rSocket, $sData.self::SOCKET_TERMINATE_BYTE);
  148.         }
  149.    
  150.         // стадия 10
  151.     private function __get_socket_data($rSocket){
  152.         $sResult = false;
  153.         while($sBuffer = @socket_read($rSocket, self::SOCKET_BLOCK_READ_SIZE)){ // типа вносим в буфер по каким то определенным критериям
  154.             $sResult.=$sBuffer;
  155.             }
  156.         return $sResult===false?null:$sResult;
  157.         }
  158.                
  159.     // стадия 11  
  160.     private function __parse_raw_command($sData){
  161.         $mData = @unserialize($sData);
  162.         if(is_array($mData) && array_key_exists(self::PARSER_RAW_SECTION_COMMAND, $mData)){
  163.             return $mData;
  164.             }
  165.         return null;
  166.         }
  167.     }
  168.        
  169. $rServer = new Cache_Server();// 1. создаем класс
  170. $rServer->runServer();// 2.2 запускаем функцию

 

Powered by ExBB FM 1.0 RC1