Clases de XML-RPC y Servidor XML-RPC
Las clases de XML-RPC de CodeIgniter le permiten envíar peticiones a otro sevidor, o establecer su propio servidor XML-RPC para recibir peticiones.
Qué es XML-RPC?
De manera simple, es una forma de dos computadores para comunicarse a través de internet usando XML. Una computadora, a la que llamaremos client, envía un pedido XML-RPC a otra computadora, la cual llamaremos el servidor. Una vez que el servidor recibe y procesa la petición envíara una respusta al cliente.
Por ejemplo, usando la API MetaWeblog, un Cliente XML-RPC (usualmente un a herramienta de publicación de escritorio) enviará una petición a un Servidor XML-RPC corriendo en su sitio. Esta petición puede ser una nueva entrada de weblog siendo envíada para publicar, o puede ser un pedidod para una editar una entrada existente. Cuando el Servidor XML-RPC recibe esta petición la examinará para determinar que clase/método debe llamar para procesar el pedido. Una vez procesado, el servidor entonces enviara un mensaje de respuesta.
Para especificaciones detalladas, puede visitar el sitio de XML-RPC.
Inicializando la clase
Como la mayoría de las otras clases en CodeIgniter, las clases XML-RPC y XML-RPCS son inicializadas en su controlador usando la función $this->load->library:
Para cargar la clase XML-RPC usará:
$this->load->library('xmlrpc');
Una vez cargada, el objeto de la librería xml-rpc estará disponible usando: $this->xmlrpc
Para cargar la clase de Servidor XML-RPC usará:
$this->load->library('xmlrpc');
$this->load->library('xmlrpcs');
Una vez cargado, el objeto de la librería xml-rpcs estará disponible usando: $this->xmlrpcs
Nota: Cuando use la clase XML-RPC Server debe cargar AMBAS clases de XML-RPC y XML-RPC Server.
Mandando un Pedido XML-RPC
Para envíar un pedido a un servidor XML-RPC debe especificar la siguiente información:
- La URL del servidor
- El método del servidor que desea llamar
- Los datos de la petición (explicados debajo).
Aquí hay un ejemplo básico que envía un simple Weblogs.com ping al Ping-o-Matic
$this->load->library('xmlrpc');
$this->xmlrpc->server('http://rpc.pingomatic.com/', 80);
$this->xmlrpc->method('weblogUpdates.ping');
$pedido = array('Mi Fotoblog', 'http://www.mi-site.com/photoblog/');
$this->xmlrpc->request($pedido);
if ( ! $this->xmlrpc->send_request())
{
echo $this->xmlrpc->display_error();
}
Explicación
El código anterior usa la clase XML-RPC, establece la URL del servidor y el método a ser llamado (weblogUpdates.ping). El pedido (en este caso, el título y la URL del sitio) es ubicado en el arreglo para transportación y compilado usando la función request(). Por último, el pedido completo es enviado. Si el método send_request() devuelve falso, mostraremos el mensaje de error envíado desde el Servidor XML-RPC.
Anatomía de una Petición
Una petición XML-RPC es simplemente los datos que son enviados al servidor XML-RPC. Cada pieza de datos en un pedido es referido como un parámetro de petición. El ejemplo anterior tiene dos parámetros: La URL y título de su sitio. Cuando el servidor XML-RPC recibe su petición, buscará los parámetros que requiera.
Los parámetros de petición deben ser ubicados en un arreglo para transportar, y cada parámetro puede ser uno de siete tipos de datos (cadenas, números, fechas, etc.). Si sus parámetros son algo distinto de cadenas debe incluir el tipo de dato en el arreglo de la petición.
Aquí hay un ejemplo de un simple arreglo con tres parámetros:
$peticion = array('John', 'Doe', 'www.algun-sitio.com');
$this->xmlrpc->request($peticion);
Si usa tipos de datos que no son cadenas, o si tiene diferentes tipos de datos, debe ubicar cada parámetro en su propio arreglo, con el tipo de dato en la segunda posición:
$peticion = array (
array('John', 'string'),
array('Doe', 'string'),
array(FALSE, 'boolean'),
array(12345, 'int')
);
$this->xmlrpc->request($peticion);
La sección Tipos de Datos de abajo tiene una lista completa de tipos de datos.
Creando un Servidor XML-RPC
Un Servidor XML-RPC actúa como un policía de tráfico de cosas, esperando por peticiones entrantes y redirigiendolas a la función apropiada para procesamiento.
Crear su propio servidor XML-RPC implica inicializar la clase Servidor XML-RPC en su controlador, donde espera las peticiones entrantes que aparezcan, y luego estableciendo un arreglo con instrucciones de mapeo para que las peticiones entrantes puedan ser enviadas a la clase/método apropiada por procesamiento.
Aquí hay un ejemplo para ilustrar:
$this->load->library('xmlrpc');
$this->load->library('xmlrpcs');
$config['functions']['nuevo_post'] = array('function' => 'Mi_blog.nueva_entrada');
$config['functions']['actualizar_post'] = array('function' => 'Mi_blog.actualizar_entrada');
$this->xmlrpcs->initialize($config);
$this->xmlrpcs->serve();
El ejemplo anterior contiene un arreglo especificando dos métodos de peticiones que el Servidor permite. Los métodos permitidos están en el lado izquierdo del arreglo. Cuando alguno de esos dos son recibidos, ellos serán enviados a la clase y método en la derecha.
En otras palabras, si un Cliente XML-RPC envía una petición al método nuevo_post, su servidor cargará la clase Mi_blog y llamará a la función nueva_entrada. Si la petición es para el método actualizar_post, su servidor cargará la clase Mi_blog y llamará a la función update_entry.
Los nombres de la función en el ejemplo aneterior son arbitrarios. Puede decidir como deben llamarse en su servidor, o si usa APIs estandarizadas, como Blogger o MetaWeblog API, usará el nombre de las funciones.
Procesando Peticiones al Servidor
Cuando el Servidor XML-RPC recibe una petición y carga la clase/método para procesar, pasará un objeto al método que contiene los datos enviados por el cliente.
Usando el ejemplo anterior, si el método nuevo_post es pedido, el servidor esperará que exista una clase con este prototipo:
class Mi_blog extends Controller {
function nuevo_post($peticion)
{
}
}
La variable $peticion es un objeto compilado por el Servidor, que contiene los datos enviados por el Cliente XML-RPC. Usando este objeto tendrá acceso a los parámetros de la petición permitiéndole procesar el pedido. Cuando termine enviará una Respuesta de vuelta al Cliente.
Debajo hay un ejemplo del mundo real, usando la API de Blogger. Uno de los métodos en la API de Blogger es getUserInfo(). Usando este método, un Cliente XML-RPC puede enviar un usuario y contraseña, y en respuesta el Servidor envía información acerca del usuario en particular (nickname, user ID, dirección de email, etc.). Aquí es como la función de procesamiento podría ser:
class Mi_blog extends Controller {
function getUserInfo($peticion)
{
$usuario = 'smitty';
$contrasena = 'secretsmittypass';
$this->load->library('xmlrpc');
$parametros = $peticion->output_parameters();
if ($parametros['1'] != $usuario AND $parametros['2'] != $contrasena)
{
return $this->xmlrpc->send_error_message('100', 'Acceso Invalido');
}
$respuesta = array(array('nickname' => array('Smitty','string'),
'userid' => array('99','string'),
'url' => array('http://susitio.com','string'),
'email' => array('jsmith@susitio.com','string'),
'apellido' => array('Smith','string'),
'nombre' => array('John','string')
),
'struct');
return $this->xmlrpc->send_response($respuesta);
}
}
Notas:
La función output_parameters() devuelve e un arreglo indexado correspondiente a los parámetros de petición enviados por el cliente. En el ejemplo anterior, los parámetros de salida serían el usuario y la contraseña.
Si el usuario y la contraseña envíados por el cleinte no son válidos, un mensaje de error es devuelto usando send_error_message().
Si la operación es exitosa, el cliente recibirá una respuesta con un arreglo conteniendo la información del usuario.
Dándole formato a una respuesta
Similar a una Petición, las Respuestas deben ser formateadas como un arreglo. Sin embargo, a diferencía de las peticiones, una respuesta es un arreglo que contiene un sólo item. El item puede ser un arreglo con varios arreglos adicionales, pero sólo puede ser un índice de arreglo principal. En otras palabras, el prototipo básico es este:
$respuesta = array('Datos respuesta', 'array');
Las respuestas, sin embargo, usualmente contienen múltiples piezas de información. Para cumplir con esto, debemos poner la respuesta en su propio arreglo, así el arreglo primario continúa conteniendo una sola pieza de datos. Aquí hay un ejemplo mostrando como puede ser logrado:
$respuesta = array (
array(
'nombre' => array('John', 'string'),
'apellido' => array('Doe', 'string'),
'miembro_id' => array(123435, 'int'),
'lista_para_hacer' => array(array('limpiar la casa', 'llamar a mamá', 'regar las plantas'), 'array'),
),
'struct'
);
Note que el arreglo anterior es formateado como un struct. Este es el más común tipo de datos para respuestas.
Como con Peticiones, una respuesta puede ser uno de los siete tipos de datos listados en la sección Tipos de Datos.
Enviando una Respuesta de Error
Si necesita enviar al cliente una respuesta de error usará lo siguiente:
return $this->xmlrpc->send_error_message('123', 'Los datos pedidos no están disponibles');
El primer parámetro es el número de error, mientras qeu el segundo parámetro es el mensaje de error.
Creando su Propio Cliente y Servidor
Para ayudar a entender todo lo que hemos cubierto hasta aquí, creemos un par de controladores que actúen como Servidores y Clientes XML-RPC. Usará el Cliente para enviar una petición al Servidor y recibir una respuesta.
El cliente
Usando un editor de texto, cree un controlador llamado xmlrpc_client.php. En él, ubique este código y guárdelo en su carpeta applications/controllers/:
Nota: En el código anterior estamos usando un "asistente de url". Puede encontrar más información en la página de Funciones Asistentes.
El Servidor
Usando un editor de texto, cree un controlador llamado xmlrpc_server.php. En él, ubique este código y guárdelo en su carpeta applications/controllers/:
Pruebelo!
Ahora visite su sitio usando una URL similar a esta:
www.su-sitio.com/index.php/xmlrpc_client/
Ahora verá el mensaje que envió al servidor, y la respuesta de vuelta a él.
El cliente que creo envía un mensaje ("Cómo estás?") al servidor, junto con la petición para el método "Saludos". El Servidor recibe la petición y lo asigna a la función "process", dónde una respuesta es devuelta.
Referencia de Funciones XML-RPC
$this->xmlrpc->server()
Establece la URL y el número de puerta del servidor al que se le enviara el pedido:
$this->xmlrpc->server('http://www.aveces.com/pings.php', 80);
$this->xmlrpc->timeout()
Establece el período de espera (en segundos) después de cuando la petición será cancelada:
$this->xmlrpc->timeout(6);
$this->xmlrpc->method()
Establece el método que será pedido al servidor XML-RPC:
$this->xmlrpc->method('metodo');
Donde método es el nombre del método.
$this->xmlrpc->request()
Toma un arreglo de datos y construye la petición que se enviará al servidor XML-RPC:
$peticion = array(array('Mi Fotoblog', 'string'), 'http://www.susitio.com/fotoblog/');
$this->xmlrpc->request($peticion);
$this->xmlrpc->send_request()
La función que envía la petición. Devuelve el booleano TRUE o FALSE basado en el éxito o fallo, permitiendo el uso condicionalmente.
$this->xmlrpc->set_debug(TRUE);
Habilita la depuración, que mostrará una variedad de información y datos de errores útiles durante el desarrollo.
$this->xmlrpc->display_error()
Devuelve un mensaje de error como cadena si su petición falló por alguna razón.
echo $this->xmlrpc->display_error();
$this->xmlrpc->display_response()
Devuelve la respuesta desde el servidor remoto una vez que el pedido es recibido. La respuesta será típicamente un arreglo asociativo.
$this->xmlrpc->display_response();
$this->xmlrpc->send_error_message()
Esta función le permite enviar un mensaje de error desde un servidor al cliente. El primer parámetro es el número de error, mientras que el segundo parámetro es el mensaje de error.
return $this->xmlrpc->send_error_message('123', 'Los datos pedidos no están disponibles');
$this->xmlrpc->send_response()
Le permite enviar la respuesta desde su servidor al cliente. Le permite enviar la respuesta desde su servidor al cliente. Un arreglo de datos válidos debe ser enviado a este método.
$respuesta = array(
array(
'flerror' => array(FALSE, 'boolean'),
'mensaje' => "Gracias por el ping!")
)
'struct');
return $this->xmlrpc->send_response($respuesta);
Tipos de Datos
De acuerdo a las especificaciones de XML-RPC hay siete tipos de valores que pueden ser envíados a través de XML-RPC:
- int o i4
- boolean
- string
- double
- dateTime.iso8601
- base64
- struct (contiene un arreglo de valores)
- array (contiene un arreglo de valores)