PHP y WDDX: Comunicación entre aplicaciones
03 de Agosto de 2007 en Programación, PHP
Lecturas: 3,579

WDDXRecientemente he descubierto y usado una forma para pasar variables de una aplicación web a otra usando un formato estándar: el WDDX.

WDDX son las siglas que definen Intercambio de Datos en Webs Distribuidas (Web Distributed Data Exchange). Básicamente, es un estándar XML para el intercambio de información estructurada entre lenguajes de programación. Podemos visitar OpenWDDX para ampliar información.
Si nos centramos en PHP, tenemos que ya vienen incorporadas unas funciones para trabajar con WDDX y nos deja centrarnos en el proyecto propiamente.

En éste artículo propongo un ejemplo orientado a un Web Service para explicar su funcionamiento.

La finalidad de WDDX es el paso de variables de un lugar a otro independientemente del lenguaje, usando una estructura XML. Así, lo que realmente se está haciendo es traducir un conjunto de variables con su contenido en una representación XML, obteniendo un paquete. Luego normalmente enviaremos ese paquete a algún sitio que lo recibirá y lo reconstruirá para obtener las variables.

Así, un ejemplo sencillo podría ser por un lado un script servidor que cuando se invoque reciba el paquete, reconstruya las variables, haga alguna acción, y devuelva una respuesta. Por otro lado, necesitaremos un cliente que enviará el paquete al servidor y espere una respuesta de éste. El WDDX obtiene su sentido cuando lo usamos como estándar de comunicación entre ambos.

Para construir el ejemplo deberemos construir los dos scripts: el cliente y el servidor. Como ambos montan y desmontan los paquetes WDDX de comunicación, podríamos crear una minibiblioteca de funciones con las acciones que ambos van a usar. Así que abriremos un nuevo archivo PHP, lo nombramos ComLayer.php (por ejemplo) y le escribimos las siguientes funciones (no olvidar los tags de inicio y fin de archivo PHP!):

PHP:
  1. function composePacket($data)
  2. {
  3. $packet_id  = wddx_packet_start("WDDX Remote Call");
  4.  
  5. wddx_add_vars($packet_id, "data");
  6.  
  7. $packet = wddx_packet_end($packet_id);
  8. $packet = urlencode($packet);
  9.  
  10. return $packet;
  11. }
  12.  
  13. function sendPacket($serialized_paquet)
  14. {
  15. $ch = curl_init();
  16. curl_setopt ($ch, CURLOPT_URL, 'http://localhost/ejemplo_wddx/servidor.php');
  17. curl_setopt ($ch, CURLOPT_HEADER, 0);
  18. curl_setopt ($ch, CURLOPT_POSTFIELDS, $serialized_paquet);
  19. curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
  20. $result = curl_exec ($ch);
  21. curl_close ($ch);
  22.  
  23. return $result;
  24. }
  25.  
  26. function parsePacket($packet)
  27. {
  28. $packet= urldecode($packet);
  29. preg_match("/(<\/wddxPacket>)/s", $packet, $m);
  30. $packet=$m[0];
  31. $parsed_packet = wddx_deserialize($packet);
  32.  
  33. return $parsed_packet;
  34. }
  35.  
  36. public static function recievePacket()
  37. {
  38. $fp = fopen("php://input", "r");
  39. $recievedPacket = '';
  40. while(!feof( $fp ))$recievedPacket.=fgets( $fp );
  41. fclose($fp);
  42.  
  43. return $recievedPacket;
  44. }

Son cuatro funciones, dos de gestión WDDX y dos de comunicación.

  • composePacket(): recibe una variable y la serializa (nombre que se le da a la acción de generar una cadena XML con su representación), y devuelve la cadena XML.
  • sendPacket(): es la encargada de enviar el paquete a una URL y obtener la respuesta. Sólo la usará el cliente.
  • parsePacket(): recibe un paquete y lo deserializa (acción inversa a serializar) en una variable con la que poder trabajar.
  • recievePacket(): se encarga de obtener el paquete cuando el script es llamado. Sólo la usará el servidor.

Si miramos el contenido de las funciones vemos que los que se encargan de la comunicación no tienen mucho secreto. Por un lado un cURL para enviar una petición y obtener un resultado, y por otro lado una gestión de entrada al PHP.

Las funciones que se encargan de serializar y deserializar los paquetes son a su vez muy simples. Pero vamos a ver cómo trabajan:

Serialización

Para la serialización debemos seguir tres simples pasos. El primero es inicializar un paquete WDDX. Se usa la función wddx_packet_start(), que recibe un texto como parámetro y devuelve un identificador de paquete que usaremos en cada acción sobre el paquete. El texto es simplemente un comentario sobre el paquete, que se incluirá en una cabecera.

Lo segundo es agregar las variables que queramos al paquete. En nuestro caso tenemos sólo una variable llamada $data. Para agregarla usamos la función wddx_add_vars() que recibe el id del paquete y a continuación todos los nombres de las variables que queramos incluir en el paquete, cada una entrecomillada y separadas por comas, como si fueran una lista de parámetros de tipo string ;)

El tercer y último paso es cerrar el paquete. Se realiza mediante la función wddx_packet_end() que recibe el id del paquete y devuelve el paquete final.

Depende de cómo lo vayamos a enviar, es interesante aplicarle al paquete un urlencode para que no perdamos carácteres en el envío si son incompatibles y luego no podamos invertir el proceso.

Deserialización

Más simple no puede ser... se usa la función wddx_deserialize() que recibe el paquete y devuelve una variable del tipo array conteniendo las variables, de forma que el nombre de la variable que habíamos introducido es el índice del array asociativo devuelto, es decir, en $parsed_packed['data'] tendremos el contenido de $data. En el ejemplo se le pasa un urldecode para recuperar los carácteres originales del paquete y hacemos una comprobación de si lo recibido es realmente un paquete WDDX. Es simple e inseguro, pero podemos hacernos una idea ;)

Script de Cliente

Vamos a por el ejemplo desde el lado cliente. Creamos un archivo PHP llamado cliente.php e incluímos la biblioteca de funciones:

PHP:
  1. include "ComLayer.php";

y agregamos algo con que jugar, seguido de la comunicación:

PHP:
  1. //declaramos la variable con algun valor
  2. $data = 25;
  3.  
  4. //crear paquete
  5. $packet = composePacket($data);
  6.  
  7. //enviar paquete
  8. $response = sendPacket($packet);
  9.  
  10. //parsear paquete
  11. $parsed_packet = parsePacket($response);
  12.  
  13. //printamos por pantalla
  14. echo $parsed_packet['resultado'];

Como se puede ver, primero se asignamos algun valor a la variable, la convertimos a un paquete enviable, la enviamos, y al recibir la respuesta recuperamos la variable de respuesta.

Script Servidor

Desde el lado servidor, deberíamos tener un script como el siguiente:

PHP:
  1. include "ComLayer.php";
  2.  
  3. $packet = recievePacket();
  4.  
  5. $request = parsePacket($packet);
  6.  
  7. $data = $request['data'];
  8.  
  9. $data = $data * 2;
  10.  
  11. $packet_response = composePacket($data);
  12.  
  13. echo $packet_response;

Que hace el servidor? Pues al llamarse procede a recoger el paquete, lo parsea para obtener la variable, efectua alguna operación (aquí podría ser cualquier cosa, desde acciones con la base de datos a lo que sea), y montamos el paquete de respuesta. Cuando tenemos el paquete de respuesta lo printamos por pantalla, porque al haber sido llamado por cURL éste recuperará lo printado como respuesta a la llamada.

El cliente, al recuperar la respuesta la printará por pantalla y veremos el resultado final.

Conclusión

Dada la escasa cantidad de operaciones a realizar para comunicarse dos scripts, que pueden estar ubicados en dos servidores distintos, WDDX se convierte en una buena herramienta para la comunicación entre sites o la distribución de trabajo, efectuándose todo de forma transparente al usuario. Obviamente existe un juego más amplio de instrucciones y opciones (aunque no mucho más) que hace que podamos extender el estándar hasta dónde queramos, incluso entre distintos lenguajes, cosa que hará nuestro sistema muy muy versátil. Podéis consultar más información en la página oficial de PHP sobre WDDX.
Salud!

Tag:
 Enviar a Fresqui

Leer los Comentarios

[ # 3958 ] Pingback desde PHP y WDDX: Comunicación entre aplicaciones // menéame [22 de Agosto de 2007, 08:15]

[…] PHP y WDDX: Comunicación entre aplicacioneswww.syntaxerror.es/2007/08/03/php-y-wddx-comunicacion-entre-… por elpixel hace pocos segundos […]

[ # 6022 ] Comment desde Carlos [28 de Septiembre de 2007, 11:30]

Hola, muy buen ejemplo para entender como funciona wddx en php pero, revisando tus scripts, no entiendo de donde sale la variable $parsed_packet[’resultado’] en el lado cliente.
gracias!

[ # 6025 ] Comment desde Xavi [28 de Septiembre de 2007, 11:53]

Buenas Carlos.
Lo que me comentas viene de la linia anterior:

$parsed_packet = parsePacket($response);

Se parsea la respuesta y se devuelve un array con el paquete parseado ;)

[ # 7617 ] Comment desde Probando [27 de Octubre de 2007, 01:09]

Monto el sitio, tal como dices, y llamando a cliente.php me dice lo siguiente:

Undefined offset: 0 in ComLayer.php on line 31

Por favor, echame una mano

Escribe un Comentario





Estadísticas