XML-RPC: организация сервера с помощью Zend Framework

В предыдущей статье мы рассмотрели как посылать XML-RPC запросы с помощью Zend Framework. Дело не из легких, но слава богу в ZF все отлажено достаточно хорошо и поэтому работает как часы. Сегодня научимся организовать собственный XML-RPC сервер, используя функционал Zend Framework.

Фреймворк

Последнюю версию Zend Framework можно скачать на странице Downloads официального сайта. На момент написания статьи последней была версия 1.11.10.

Далее предполагается, что читатель знаком с шаблоном проектирования MVC, его реализацией в Zend Framework и основами создания проектов. Поэтому все подробности о создании и настройки проектов в этой статье мы рассматривать не будем.

Быстрый старт

Начнем, пожалуй, с самого простого. С кода функций, которые будут доступны для вызова через сервер. Для этого в папке library создадим еще одну папку и назовем ее Service. В ней разместим пару файлов с кодом тестовых функций.

Для начала рассмотрим, как сервер справляется с обработкой обычных функций.

library/Service/functions.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
 
/**
* Test function
* @param int value1
* @param int value2
* @return array
**/
function testFunction($var1, $var2){
 
return array($var1, $var2);
 
}
 
?>

С кодом функции, я думаю, всем понятно. Она возвращает переданные параметры в виде массива. Более важным здесь является комментарий функции. Он должен быть оформлен в стиле PHPDoc. В комментарии нужно написать тип передаваемых параметров и тип возвращаемого значения. Замечание: если функция возвращает ассоциативный массив, то тип нужно указывать struct.

Теперь напишем контроллер, в котором расположим код самого сервера и сразу же добавим функцию, описанную выше, к серверу.

application/controllers/ServerController.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
 
class ServerController extends Zend_Controller_Action{
 
 
 
  public function indexAction(){
 
    //подключаем файл с функцией
    require_once 'Service/functions.php';
 
    //создаем объект сервера
    $server = new Zend_XmlRpc_Server();
    //добавляем функцию
    $server->addFunction('testFunction', 'webjunior');
 
	//начинаем работу сервера
    die($server->handle());
 
  }
}

Теперь, обратившись к серверу, мы можем вызвать функцию webjunior.testFunction. О том, как работать с XML-RPC клиентом в ZF вы можете почитать в предыдущей статье.

Всю работу по организации сервера берет на себя класс Zend_XmlRpc_Server. Он, как и все сервера в ZF, является потомком класса Zend_Server_Abstract.

Для добавления функций в сервер используется метод

void Zend_XmlRpc_Server::addFunction(
string|array $function, string $namespace='')

Параметры:

  • string|array $function — имя функции, которая добавляется к серверу. Если функций несколько, то их можно передать массивом;

  • string $namespace — пространство имен, к которому добавляется функция. Параметр не обязателен.

Сам метод ничего не возвращает по окончанию работы. Но бросает исключение типа Zend_XmlRpc_Server_Exception в следующих случаях:

  • $function не является строкой и не является массивом;

  • элемент массива $function не является строкой;

  • указанная функция не существует.

Для запуска сервера вызываем метод

Zend_XmlRpc_Server::handle(Zend_XmlRpc_Request $request=false)

Параметр:

  • Zend_XmlRpc_Request $request — объект запроса. Если нужна какая-то особая обработка запроса, то передаем объект здесь. По умолчанию установлен в false.

Этот метод не бросает никаких исключений, но возвращает объект класса Zend_XmlRpc_Response. Или объект класса Zend_XmlRpc_Fault в случае ошибки.

Классы

Теперь рассмотрим, как добавлять методы классов к серверу. Вот код простого класса, методы которого можно добавить к серверу.

library/Service/Test.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
 
 
class Test{
 
  /**
  * Test method
  * @param string $val1 First param
  * @param base64 $val2 Second param
  * @return struct combined in array
  **/
  public function combine($val1, $val2){
    return $this->_combine($val1, $val2);
  }
 
 
  private function _combine($val1, $val2){
    return array('val1'=>$val1, 'val2'=>base64_encode($val2));
  }
 
}

Как и для функций, добавляемые методы должны иметь комментарий в стиле phpDoc. Добавляются только публичные методы.

Немного изменим код сервера, представленного выше. Добавим еще этот класс.

application/controllers/ServerController.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
 
class ServerController extends Zend_Controller_Action{
 
 
 
  public function indexAction(){
 
    //подключаем файлы с функцией и классом
    require_once 'Service/functions.php';
    require_once 'Service/Test.php';
    try{
    //создаем объект сервера
    $server = new Zend_XmlRpc_Server();
 
    //добавляем функцию
    $server->addFunction('testFunction', 'webjunior');
    //добавляем публичные методы класса
    $server->setClass('Test', 'webjunior');
    //запускаем сервер
    die($server->handle());
    }catch(Exception $e){
      die($e->getCode());
    }
 
  }
}

Теперь у нашего сервера есть две функции webjunior.testFunction и webjunior.combine.

Этот сервер отличается от предыдущего вызовом всего лишь одного метода:

void Zend_XmlRpc_Server::setClass(
string|object $class, string $namespace = '', 
mixed $argv = null)

Метод добавляет все публичные методы класса указанного в параметре $class.

Параметры:

  • string|object $class — класс, методы которого будут добавлены к серверу. Это может быть строка или объект самого класса;

  • string $namespace — пространство имен. По умолчанию пустая строка;

  • mixed $argv — все параметры, которые переданы после $namespace будут переданы в вызываемые методы.

Кеширование

Рассмотренной выше функциональности вполне достаточно для понимания основ создания XML-RPC сервера в ZF. Теперь рассмотрим случай, когда нагрузка на сервер настолько большая, что железу просто не под силу обработать все поступившие запросы. Здесь на выручку приходит кеширование.

Кеширование серверов в ZF на данный момент не на высшем уровне. Кешировние XML-RPC сервера не исключение. Сейчас есть только примитивный функционал, который дает возможность добавить сервер в кеш, извлечь его из кеша или совсем удалить сервер из кеша.

Рассмотрим простой пример организации кеша для XML-RPC сервера.

application/controllers/ServerController.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
 
class ServerController extends Zend_Controller_Action{
 
 
//организуем кеш
public function cachedAction(){
 
	//создаем сервер
    $server = new Zend_XmlRpc_Server();
 
   //подключаем весь функционал сервера
   require_once 'Service/Test.php';
    require_once 'Service/functions.php';
 
	//пытаемся достать сервер из кеша
    if(!Zend_XmlRpc_Server_Cache::get(
APPLICATION_PATH.'/../tmp/cache.file', $server)){
 
    //если сервер не удалось получить, то добавляем функции вручную
    $server->addFunction('testFunction', 'webjunior');
    $server->setClass('Test', 'webjunior');
 
	//сохраняем сервер в кеш
    Zend_XmlRpc_Server_Cache::save(
APPLICATION_PATH.'/../tmp/cache.file', $server);
 
    }
 
	//запускаем сервер
    die($server->handle());
 
  }
}

Для кеширования сервера используем класс Zend_XmlRpc_Server_Cache. Метод

bool Zend_XmlRpc_Server_Cache::get(
string $filename, Zend_Server_Interface $server)

получает сервер из кеша.

Параметры:

  • string $filename — имя файла-кеша, в котором сохранен наш сервер;

  • Zend_Server_Interface $server — объект класса-сервера, в который запишется закешированный сервер;

Метод вызывается только статично, поскольку объявлен как public static. Возвращает булевое значение, которое говорит о результате операции.

Для сохранения сервера в кеш есть метод

bool Zend_XmlRpc_Server_Cache::save(
string $filename, Zend_Server_Interface $server)

Параметры:

  • string $filename — имя файла, в который будет сохранен кеш;

  • Zend_Server_Interface $server — объект класса-сервера, который сохраняем в кеше.

Этот метод тоже вызывается только статично. И возвращает булевое значение.

И третий метод, который доступен при кешировании,

bool Zend_XmlRpc_Server_Cache::delete(string $filename)

удаляет файл кеша, а вместе с ним и все закешированные данные.

Параметры:

  • string $filename — имя файла-кеша.

Этот метод, как и предыдущие, вызывается статично и возвращает булевое значение.

А какими инструментами в Zend Framework пользуетесь вы и о чем вам больше всего хотелось почитать? Не стесняйтесь, пишите в комментариях.



Читайте все статьи цикла:

Популярность: 2%


Интересное из других блогов:

2leep.com

И не забывайте комментировать статью.

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

Отзывов: 4 на «XML-RPC: организация сервера с помощью Zend Framework»

  1. Автор: aktuba, 13 сентября 2011 в 19:56

    использует Firefox 6.0.2 Firefox 6.0.2 на Windows 7 Windows 7

    Не увидел упоминания про один неприятный баг. Если на сервере установлен eAccelerator, то Zend_XMLRPC_Server будет жестоко глючить – начиная со второго запроса отдавать данные первого… Сам столкнулся, когда реализовывал. Весь инет перерыл, пока нашел причину. Лечение простое:

    @ini_set(‘eaccelerator.enable’, ’0′);
    @ini_set(‘eaccelerator.optimizer’, ’0′);

    • Автор: web-junior, 13 сентября 2011 в 21:59

      использует Firefox 6.0.1 Firefox 6.0.1 на GNU/Linux x64 GNU/Linux x64

      Да, с eAccelerator одни проблемы в этом случае. Единственное, что выручает в этом случае – полное отключение.
      Спасибо, что напомнили нам об этом.

  2. Автор: Saint_Byte, 20 сентября 2011 в 07:23

    использует Google Chrome 14.0.835.163 Google Chrome 14.0.835.163 на Windows XP Windows XP

    Все прикольно но как-то сложно , куда такая штука может пригодиться . Расскажите лучше как пропатчить Zend_View что чтоб отдавать массив в акшене а во вьюхе показывать как json

    • Автор: web-junior, 20 сентября 2011 в 11:09

      использует Firefox 6.0.1 Firefox 6.0.1 на GNU/Linux x64 GNU/Linux x64

      Такая штука может пригодиться при создании XML-RPC сервера на ZF. Конечно не каждый день приходится делать это. Но если понадобиться, то вы будете знать где искать примеры и инструкции.

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

RSS-лента комментариев. Адрес для трекбека

Трэкбэки и пинги:

Ваш отзыв

Вы можете использовать следующие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">

Нажимая на кнопку "Добавить" вы принимаете правила комментирования