Классы XML-RPC и XML-RPC Server
Класс XML-RPC позволяет вам отправлять запросы на другой сервер, или установить собственный сервер XML-RPC, принимающий запросы.
Что такое XML-RPC?
Все очень просто — это способ, которым два компьютера могут соединяться друг с другом через интернет, используя XML. Один компьютер, который называется клиент, отправляет запрос XML-RPC другому компьютеру, который называется сервер. Сервер принимает и обрабатывает запрос, и посылает назад ответ клиенту.
Например, используя MetaWeblog API, клиент XML-RPC (обычно десктопный инструмент для публикаций) отправляет запрос серверу XML-RPC, запущенному на сайте. Этот запрос может быть новой темой в блоге, которую нужно опубликовать, или запрос на редактирование существующей темы. Когда сервер XML-RPC принимает этот запрос, он будет изучать его, чтобы определить, какой класс/метод может быть вызван для обработки запроса. После обработки сервер вернет ответное сообщение.
Для более подробной информации можете посетить сайт XML-RPC.
Инициализация класса
Как и большинство других классов, классы XML-RPC и XML-RPCS инициализируются в вашем контроллере посредством функции $this->load->library:
Для того, чтобы загрузить класс XML-RPC, используйте:
$this->load->library('xmlrpc');
Загруженный класс доступен как: $this->xmlrpc
Для того, чтобы загрузить класс XML-RPC Server, используйте:
$this->load->library('xmlrpc');
$this->load->library('xmlrpcs');
Загруженные класс xml-rpcs будет доступен как: $this->xmlrpcs
Примечание: При использовании класса XML-RPC Server вы должны загрузить ОБА класса — XML-RPC и XML-RPC Server.
Отправка запроса XML-RPC
Для того, чтобы отправить запрос серверу XML-RPC, вы должны указать следующую информацию:
- URL сервера
- Метод вызова
- Данные запроса (разъяснено ниже).
Вот основной пример, как отправить простой пинг Weblogs.com к Ping-o-Matic
$this->load->library('xmlrpc');
$this->xmlrpc->server('http://rpc.pingomatic.com/', 80);
$this->xmlrpc->method('weblogUpdates.ping');
$request = array('My Photoblog', 'http://www.my-site.com/photoblog/');
$this->xmlrpc->request($request);
if ( ! $this->xmlrpc->send_request())
{
echo $this->xmlrpc->display_error();
}
Объяснение
Код выше инициализирует класс XML-RPC, устанавливает URL сервера и метод, которым он будет вызван (weblogUpdates.ping). Запрос (в этом случае, название и URL вашего сайта) размещается в массиве для транспортировки, и компилируется посредством функции request(). Наконец, подготовленный запрос отправляется. Если метод send_request() возвращает FALSE, мы выведем сообщения об ошибках, возвращенные сервером XML-RPC.
Анатомия запроса
Запрос XML-RPC - это просто данные, которые вы отправляете серверу XML-RPC. Каждый элемент данных в запросе соотносится с параметром запроса. В примере выше присутствуют два параметра: URL и название вашего сайта. Когда сервер XML-RPC принимает ваш запрос, он будет проверять требуемые параметры.
Параметры запроса должны быть расположены в массиве для транспортировки, и каждый параметр может быть одного из семи типов данных (строки, числа, даты и т.д.). Если ваш параметр не строкового типа, включите тип данных в массив запроса.
Вот пример простого массива с тремя параметрами:
$request = array('John', 'Doe', 'www.some-site.com');
$this->xmlrpc->request($request);
Если вы используете типы данных кроме строк, или вы используете несколько различных типов данных, разместите каждый параметр в собственном массиве, с указанием типа данных во второй позиции:
$request = array (
array('John', 'string'),
array('Doe', 'string'),
array(FALSE, 'boolean'),
array(12345, 'int')
);
$this->xmlrpc->request($request);
Раздел Типы данных ниже содержит полный список доступных типов данных.
Создание сервера XML-RPC
Сервер XML-RPC действует как инспектор ГИБДД, ожидая входящие запросы, и переадресуя их к соответствующим функциям для последующей обработки
Чтобы создать ваш собственный сервер XML-RPC, включите инициализацию класса XLM-RPC Server в вашем контроллере там, где вы ожидаете появление запросов, затем установите массив с инструкциями по разбору входящих запросов, которые могут быть переданы соответствующему классу/методу для обработки.
Вот пример:
$this->load->library('xmlrpc');
$this->load->library('xmlrpcs');
$config['functions']['new_post'] = array('function' => 'My_blog.new_entry'),
$config['functions']['update_post'] = array('function' => 'My_blog.update_entry');
$config['object'] = $this;
$this->xmlrpcs->initialize($config);
$this->xmlrpcs->serve();
Пример выше содержит массив с двумя разрешенными методами запросов. Разрешенные методы в левой части массива. Когда приходит запрос разрешенного метода, он будет направлен классу и функции, указанной справа.
Ключ 'object' - это специальный ключ, который вы передаете объекту класса в случае, если необходимо, чтобы получающий метод не являлся частью суперобъекта CodeIgniter.
Другими словами, если клиент XLM-RPC отправляет запрос для метода new_post, ваш сервер загрузит класс My_blog и вызовет его функцию new_entry. Если пришел запрос метода update_post, ваш сервер загрузит класс My_blog и вызовет функцию update_entry.
Имена функций в примере выше произвольные. Вы самостоятельно решаете, как они будут называться на вашем сервере, или, если вы используете стандартизированные API, как Blogger или MetaWeblog API, вы будете использовать имена функций, указанные в них.
Есть два различных ключа конфигурации, которые вы можете использовать при инициализации серверного класса: debug может быть установлен в TRUE в случае, если включена отладка, и xss_clean может быть установлен в FALSE для предотвращения обработки данных фильтром XSS.
Обработка серверного запроса
Когда сервер XML-RPC получает запросы и загружает класс/метод для обработки, он передает объект методу, содержащему данные, отправленные клиентом.
Используя пример выше, если запрошен метод new_post, сервер будет ожидать существующий класс в соответствии с этим прототипом:
class My_blog extends CI_Controller {
function new_post($request)
{
}
}
Переменная $request - это объект, скомпилированный сервером, который содержит данные, отправленные клиентом XML-RPC. Используя этот объект, вы можете получать доступ к параметрам запроса, включенных вами в обработку запроса. При завершении обработки вы отправите Ответ назад клиенту.
Ниже реальный пример, использующий Blogger API. Один из методов Blogger API - это getUserInfo(). Используя этот метод, клиент XML-RPC может отправлять серверу имя и пароль, и в ответ сервер отправляет информации о конкретном пользователе (ник, ID пользователя, адрес электронной почты и т.д.). Вот так может выглядеть функция обработки:
class My_blog extends CI_Controller {
function getUserInfo($request)
{
$username = 'smitty';
$password = 'secretsmittypass';
$this->load->library('xmlrpc');
$parameters = $request->output_parameters();
if ($parameters['1'] != $username AND $parameters['2'] != $password)
{
return $this->xmlrpc->send_error_message('100', 'Invalid Access');
}
$response = array(array('nickname' => array('Smitty','string'),
'userid' => array('99','string'),
'url' => array('http://yoursite.com','string'),
'email' => array('jsmith@yoursite.com','string'),
'lastname' => array('Smith','string'),
'firstname' => array('John','string')
),
'struct');
return $this->xmlrpc->send_response($response);
}
}
Примечания:
Функция output_parameters() извлекает индексированный массив, соответствующий параметрам запроса, отправленных клиентом. В примере выше выходные параметры будут именем пользователя и паролем.
Если имя пользователя и пароль, отправленые клиентом, неправильные, сообщение об ошибке возвращается, используя send_error_message().
Если операция успешна, клиент получает назад ответный массив, содержащий информацию о пользователе.
Форматирование ответа
Также, как и Запросы, Ответы должны быть отформатированы как массив. Однако, в отличие от запросов, ответ — это массив, который содержит единственный элемент. Этот элемент может быть массивом из нескольких дополнительных массивов, но они могут иметь только один единственный первичный индекс. Другими словами, основной прототип выглядит так:
$response = array('Response data', 'array');
Ответы обычно содержат множество элементов информации. Для достижения этого мы должны положить ответ в собственный массив так, что основной массив по-прежнему будет содержать единственный элемент данных. Вот пример того, как это сделать:
$response = array (
array(
'first_name' => array('John', 'string'),
'last_name' => array('Doe', 'string'),
'member_id' => array(123435, 'int'),
'todo_list' => array(array('clean house', 'call mom', 'water plants'), 'array'),
),
'struct'
);
Обратите внимание, что массив выше отформатирован как структура. Это наиболее распространенный тип данных для ответов.
Как с запросами, ответы могут быть одного из семи типов данных, перечисленных в разделе Типы данных.
Отправка ответа об ошибке
Если вы нуждаетесь в отправке клиенту ответа об ошибке, используйте следующее:
return $this->xmlrpc->send_error_message('123', 'Requested data not available');
Первый параметр - это номер ошибки, второй — текст сообщения об ошибке.
Создание ваших собственных клиента и сервера
Для облегчения понимания вышенаписанного, давайте создадим пару контроллеров, которые будут XML-RPC клиентом и сервером. Вы будете использовать клиент для отправки запроса серверу, и получения ответа.
Клиент
Используя текстовый редактор, создайте контроллер с названием xmlrpc_client.php.
В нем разместите этот код и сохраните его в вашу директорию applications/controllers/
Примечание:
В коде выше мы используем помощник URL. Вы можете найти больше информации на странице Функции помощников. Используя текстовый редактор, создайте контроллер с названием xmlrpc_server.php.
Разместите этот код в нем и сохраните в вашу директорию applications/controllers/: Теперь посетите ваш сайт, используя URL, соответствующий этому: Вы должны увидеть сообщение, отправленное серверу, и его ответ на него, возвращенный вам. Клиент, которого вы создали, отправляет сообщение ("How's is going?")
серверу, вместе с просьбой ответить методом "Greetings".
Сервер получает запрос и передает его функции "process", которая возвращает ответ. Если вы желаете использовать ассоциативный массив в параметрах вашего метода, вы должны использовать структурный тип данных: You can retrieve the associative array when processing the request in the Server. Устанавливает URL и номер порта сервера, которому отправляется запрос: Устанавливает время таймаута (в секундах), после которого запрос будет отменен: Устанавливает метод, который будет отвечать от сервера XML-RPC: Где method — имя метода. Принимает массив данных и строит запрос, который будет отправлен серверу XML-RPC: Функция отправки запроса. Возвращает булево TRUE или FALSE, в зависимости от успеха или неудачи. Используйте это в условии. Включает отладку, которая будет отображать различную информацию и данные об ошибках, полезные при разработке. Возвращает строкой сообщение об ошибке, если ваш запрос неудачен по некоторым причинам. Возвращает ответ от удаленного сервера. Ответ обычно является ассоциативным массивом. Эта функция позволяет вам отправить сообщение об ошибке от вашего сервера клиенту.
Первый параметр - это номер ошибки, второй — текст сообщения об ошибке. Позволяет вам отправить ответ от вашего сервера клиенту. Этому методу должен быть передан массив с корректными данными. В соответствии со спецификацией XML-RPC
есть семь типов значений, которые можно отправлять через XML-RPC:Сервер
Попробуйте!
example.com/index.php/xmlrpc_client/
Использование ассоциативного массива в параметре запроса
$request = array(
array(
// Param 0
array(
'name'=>'John'
),
'struct'
),
array(
// Param 1
array(
'size'=>'large',
'shape'=>'round'
),
'struct'
)
);
$this->xmlrpc->request($request);$parameters = $request->output_parameters();
$name = $parameters['0']['name'];
$size = $parameters['1']['size'];
$size = $parameters['1']['shape']; Справка по функциям XML-RPC
$this->xmlrpc->server()
$this->xmlrpc->server('http://www.sometimes.com/pings.php', 80);
$this->xmlrpc->timeout()
$this->xmlrpc->timeout(6);
$this->xmlrpc->method()
$this->xmlrpc->method('method');
$this->xmlrpc->request()
$request = array(array('My Photoblog', 'string'), 'http://www.yoursite.com/photoblog/');
$this->xmlrpc->request($request);$this->xmlrpc->send_request()
$this->xmlrpc->set_debug(TRUE);
$this->xmlrpc->display_error()
echo $this->xmlrpc->display_error();
$this->xmlrpc->display_response()
$this->xmlrpc->display_response();
$this->xmlrpc->send_error_message()
return $this->xmlrpc->send_error_message('123', 'Requested data not available');
$this->xmlrpc->send_response()
$response = array(
array(
'flerror' => array(FALSE, 'boolean'),
'message' => "Thanks for the ping!"
)
'struct');
return $this->xmlrpc->send_response($response);Типы данных