Однако же концепция, которую я вкладываю в понятие "кеш", должна быть понятна на данном примере. Кроме того, для изучения может быть полезен просмотр кода - в плане работы с сетью через сокеты. Пример достаточно прост, не имеет множества вещей, которые были бы полезны (полной обработки ошибок, или, например, попыток повторных соединений), но, так как в любом случае интерес этот код может представлять лишь академический, а не практический, я не углублялся в такие детали.
Как это работает. Очень просто - существует кеш-сервер, который слушает входящие соединения на предопределенном порту. Он обрабатывает клиентов, которые с ним соединяются, и, если те шлют команды по протоколу, который он понимает, делает всю полезную работу - хранит кеш, предоставляет значение по ключу и т.п. Код сервера:
PHP:
скопировать код в буфер обмена
скопировать код в буфер обмена
- class Cache_Server
- {
- const PARSER_RAW_SECTION_COMMAND = 'raw_command';
- const PARSER_RAW_SECTION_DATA = 'raw_data';
- const HANDLER_COMMAND_COMMON_PREFIX = '_hook_';
- const HANDLER_COMMAND_SET_KEY = 'key';
- const HANDLER_COMMAND_SET_DATA = 'data';
- const HANDLER_COMMAND_SET_SUCCESS = 1;
- const HANDLER_COMMAND_SET_FAILURE = 0;
- const SOCKET_BLOCK_READ_SIZE = 64;
- const SOCKET_TERMINATE_BYTE = "\0";
- const ERROR_SERVER_SETUP_MESSAGE = "Could not setup server socket";
- const ERROR_SERVER_SETUP_CODE = 2;
- protected $_sAddress = '127.0.0.1';
- protected $_sPort = '23540';
- private $__rSocket = null;
- public function __construct($sHost=null, $sPort=null)
- {
- {
- $this->_sAddress= $sHost;
- $this->_sPort = $sPort;
- }
- }
- public function runServer()
- {
- if(!$this->__setup_socket())
- {
- $this->setError(self::ERROR_SERVER_SETUP_CODE, self::ERROR_SERVER_SETUP_MESSAGE);
- return false;
- }
- while(true)
- {
- $this->_check_clients();
- $this->_listen_clients();
- }
- }
- //errors functions:
- public function getLastError()
- {
- }
- public function setError($iCode, $sMessage)
- {
- }
- //cache functions:
- public function getKey($mClient, $mKey)
- {
- $sKey = $this->__generate_key_hash($mClient, $mKey);
- }
- public function setKey($mClient, $mKey, $mValue)
- {
- {
- }
- else
- {
- $this->__rgCache[$this->__generate_key_hash($mClient, $mKey)]=$mValue;
- }
- }
- //clients functions:
- protected function _check_clients()
- {
- {
- $this->_rgClients[] = $rNewc;
- }
- }
- protected function _listen_clients($bCheckAlive=false)
- {
- foreach($this->_rgClients as $iIndex => $rClient)
- {
- if($sData = $this->__get_socket_data($rClient))
- {
- if($rgCommand = $this->__parse_raw_command($sData))
- {
- $this->_execute_command($iIndex, $rgCommand[self::PARSER_RAW_SECTION_COMMAND], $rgCommand[self::PARSER_RAW_SECTION_DATA]);
- }
- }
- }
- }
- //command handle functions:
- protected function _execute_command($mClient, $sCommand, $mParameters)
- {
- //need to use prefix, so call will be more safe:
- {
- $this->$sCommand($mClient, $mParameters);
- }
- }
- protected function _hook_get($mClient, $mParameters)
- {
- $this->__send_socket_data($mClient, $this->getKey($mClient, (string)$mParameters));
- }
- protected function _hook_set($mClient, $mParameters)
- {
- {
- {
- $sKey = $rgParameters[self::HANDLER_COMMAND_SET_KEY];
- $this->setKey($mClient, $sKey, null);
- {
- $this->setKey($mClient, $sKey, $rgParameters[self::HANDLER_COMMAND_SET_DATA]);
- }
- $this->__send_socket_data($mClient, self::HANDLER_COMMAND_SET_SUCCESS);
- return true;
- }
- }
- $this->__send_socket_data($mClient, self::HANDLER_COMMAND_SET_FAILURE);
- return false;
- }
- private function __generate_key_hash($mClient, $mKey)
- {
- }
- //socket functions:
- private function __setup_socket()
- {
- {
- return false;
- }
- return true;
- }
- private function __send_socket_data($rSocket, $sData)
- {
- }
- private function __get_socket_data($rSocket)
- {
- $sResult = false;
- {
- $sResult.=$sBuffer;
- }
- return $sResult===false?null:$sResult;
- }
- private function __parse_raw_command($sData)
- {
- {
- return $mData;
- }
- return null;
- }
- }