Como acceder a múltiples servicios web en paralelo con PHP

Octubre 11, 2009 by Demián Rodríguez 3 Comments »

Veamos el caso de una aplicación Web donde se realizan búsquedas en base a cierta información ingresada por el usuario, y para generar los resultados, el sistema debe consultar varios servicios web, los cuales tardan varios segundos en responder. Habría que buscar una forma de minimizar el tiempo de búsqueda para que al cliente le lleguen los resultados antes que la muerte.
La solución que propongo fue aplicada en un sistema de búsqueda y reserva de vuelos y hoteles.

Se pueden utilizar varias técnicas, yo tuve en cuenta las siguientes:

  • Acceder a los web services en forma concurrente utilizando CURL: Se podría buscar y generar la página de resultados directamente, o hacerlo mediante AJAX, lo cual nos permitiría hacer un polling e ir obteniendo resultados parciales.
    Sería la solución mas elegante, pero hay que tener en cuenta que desgraciadamente no todos los web services son de tipo REST y algunos usan SOAP, por lo tanto se hace dificil implementarlo usando esta librería porque habría que generar el XML e interpretar la respuesta manualmente. Mucho trabajo a mi parecer.
  • Implementar threads: Quizás piensen en el suicidio antes de tener en cuenta esta opción.
  • Buscar la solución en el lado del cliente y enviar una petición AJAX por cada web service: Aún así tenemos el problema de los límites de conección por host que imponen algunos navegadores como IE 6 y 7.

En principio opté por la última opción, pero me vi forzado a descartar el uso de AJAX debido a que algunos browsers imponen un límite de 2 conecciones concurrentes por host y yo necesito consultar 6 servicios web. Para evitar este límite tenemos que engañar al navegador creando al menos 3 subdominios, los cuales nos permitiría realizar 6 peticiones en paralelo, 2 por cada uno.
Quizás la solución no es muy elegante pero es muy usada para agilizar la descarga de los distintos componentes de la página. Tal es el caso de Google Maps, que utiliza subdominios mt0.google.com, mt1.google.com, mt2.google.com, etc.
Si bien no podemos enviar una petición a otro subdominio usando AJAX (hasta el momento), podemos inyectar un script en el documento y cumpliría la misma función, siempre y cuando la respuesta sea en formato JSON. Aca va un ejemplo usando jQuery:

$(function() {
    var webServices = [1,2,3,4,5,6]; // id's de los webservices
    var count = 1, host;
    for (var i = 0; i < webServices.length; i++) {
        // generamos un host
        host = 'http://ws' + count + '.' + location.host + '/search?ws=' + i;
        if ((i+1)%2 == 0) count++;
        // enviamos el request, jQuery inyecta el script en el documento al detectar otro dominio
        $.getJSON(host, function(json) {
            // actualizamos los resultados...
            $('#results').html(json.results);
        });
    }
});

Aunque en el título menciono a PHP, mas bien nos limita en vez de darnos una solución práctica.

 

Geolocalizando al usuario

Julio 14, 2009 by Demián Rodríguez 2 Comments »

Una de las nuevas características de los navegadores actuales que introdujeron soporte para HTML5 es la API de Geolocalización, la cual nos permite obtener las coordenadas de la posición actual del usuario. Actualmente solo Firefox 3.5  y Opera 10 beta lo implementan en forma nativa, pero el servicio también está disponible instalando Gears.

La API hace transparente al programador la forma en que se obtiene la posición del usuario. Hay varias formas de determinarla y éstas dependen de la plataforma y el dispositivo del usuario. Si se accede desde un dispositivo con GPS, se podrá obtener las coordenadas en forma casi exacta. Si se accede desde una PC o móvil sin GPS, el navegador envía una solicitud al servicio de geolocalización de Google con información sobre los puntos de acceso WiFi cercanos, aunque en este último, la exactitud de la posición obtenida deja mucho que desear en algunos casos.

A continuación les dejo un código de prueba que usé para determinar la localización con Firefox 3.5.
Irónicamente, a pesar de estar ubicado en el barrio de Recoleta, las coordenadas resultantes me ubican en Puerto Madero a metros de las oficinas de Google.

if (navigator.geolocation) {
    // nos aseguramos de que el browser soporte la API
    navigator.geolocation.getCurrentPosition(function(position) {
    	var latitude = position.coords.latitude;
    	var longitude = position.coords.longitude;
        // aca podemos ubicar el punto en un mapa
        // o hacer una geocodificación inversa para obtener la dirección
    }, function(error) {
	// error es un objeto con las siguientes propiedades:
    	// - code: código de error
    	// - message: mensaje de error
    });
}

Al método getCurrentPosition() se le envía como primer parámetro un callback que recibirá un objeto con las propiedades de la posición. El segundo parámetro es opcional y es un callback que se llamará si ocurre algún error en el proceso.

Si usamos la API de Gears, el proceso es el mismo, salvo que tenemos algunas opciones adicionales, incluso el objeto position ya nos devuelve la dirección luego de hacer una geocodificación inversa.

Enlaces útiles:

 

¿Ya podemos usar HTML 5?

Junio 15, 2009 by Demián Rodríguez 2 Comments »

Vamos a comentar algunas de las nuevas características de este nuevo lenguaje que pretende reemplazar al ya decrépito HTML 4.01. Esta nueva revisión del lenguaje nació hace unos años bajo el nombre Web Applications 1.0 y continúa siendo desarrollado activamente por el grupo WHATWG como HTML5, y además su otra variante XHTML5. Se dice que estará completo para el 2012, pero la mayoría de los navegadores actuales ya implementan gran parte de las nuevas características del lenguaje.

Algunas de las mejoras que nos provee HTML5 son las siguientes:

  • Nuevos tags como <header>, <footer>, <section>, etc.  En su mayoría son reemplazos semánticos para los bloques genéricos como <div> o <span>.
  • La incorporación de Web Forms 2.0, una actualización para el manejo de formularios que agrega nuevos tipos de datos y facilidad para la validación de campos.
  • Se eliminaron elementos como <font> y <center>, cuya funcionalidad puede ser reemplazada por CSS.
  • Grandes cambios en la API del DOM, incluyendo soporte para dibujar en 2D usando el nuevo elemento <canvas>, soporte para aplicaciones offline, Drag & Drop, controles de reproducción multimedia para usar con los elementos <audio> y <video>, manejo avanzado del historial y mucho mas.

HTML5 nos dá la opción de crear el documento usando la vieja sintaxis compatible con HTML 4 u optar por un documento XML.

Ejemplo para la primera opción:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Documento de ejemplo</title>
  </head>
  <body>
    <p><img src="/images/logo.png" alt="" /> Hola mundo</p>
  </body>
</html>

Datos importantes:

  • El documento se sirve como Content-Type: text/html
  • El DOCTYPE  es requerido y no necesita referirse a ningún DTD.
  • Nueva forma de especificar el juego de caracteres mediante el atributo charset del <meta>.
  • Por cuestiones de compatibilidad, se permite cerrar los tags vacíos como <img>, <input> o <br> con una barra, usando la misma sintaxis que XML.
  • Ventaja: compatible con navegadores que no soportan HTML5

Ejemplo conforme a la sintaxis XML:

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Documento de ejemplo</title>
  </head>
  <body>
    <p><img src="/images/logo.png" alt="" /> Hola mundo</p>
  </body>
</html>

Datos importantes:

  • El documento se sirve como Content-Type: application/xhtml+xml
  • El DOCTYPE  es opcional.
  • Se requiere definir el namespace como http://www.w3.org/1999/xhtml
  • Alcanza con especificar el charset en la definición del XML.
  • Ventaja: obliga a escribir código XML válido.

Uno de los grandes cambios que debemos tener en cuenta es la forma en que se sirve el documento. Hasta ahora estábamos acostumbrados a enviarle al navegador un documento XHTML como text/html por problemas con navegadores defectuosos como Internet Explorer ciertos navegadores. Pero esto hará que el navegador interprete erróneamente el documento XML como HTML.

Lo que no queda del todo claro es como va a ser la compatibilidad hacia atrás. No solo tendremos que lidiar con navegadores “prehistóricos” por un largo tiempo, sino que además se han introducido cambios en el significado de varios elementos como <strong>, <small>, <b>, <i>, que implicaría tener que reescribir parte de la estructura del documento.

Adicionalmente, ¿qué sucede si servimos un documento en HTML5 en un browser que no lo soporta? ¿Cómo se interpretan los nuevos elementos?
Uno de los problemas encontrados en Internet Explorer para todas sus versiones es la incapacidad de renderizar y darle estilo a los elementos desconocidos. Para esto se logró hallar un hack, el cual consiste en crear el elemento dińamicamente usando el método del DOM document.createElement() en el head del documento.

Les dejo algunos enlaces relevantes (en inglés):

 

Leyes para la producción de software, un paso necesario.

Junio 4, 2009 by Javier Guzmán 2 Comments »

Una propuesta presentada por la Comisión Europea, sugiere que las compañías desarrolladoras de software deben ser responsables por la seguridad y eficacia de sus productos (ver nota de Zdnet.co.uk). Diferentes representantes de productoras de software han puesto un grito en el cielo por esta medida, sin embargo una adecuada regulación de la industria es necesaria para el bien de la sociedad y de la industria misma.

Gran parte del negocio principal de nuestra empresa, ZedPlan, es el desarrollo de software, por lo cual serían “más fáciles las cosas para nosotros” sin leyes que regulen nuestra producción. Pero la responsabilidad con nuestros clientes y con la sociedad existe siempre, independientemente de que existan regulaciones o no. En el corto plazo, puede que a las empresas les generen costos que antes no tenían, pero en el mediano y largo plazo se verán compensadas, ya que la sociedad se verá favorecida con productos de mayor calidad, y confiará más en el sector, haciendo que invierta más en él, o que, por ejemplo, se animen mucho más a realizar transacciones a través de Internet.

Otro beneficio para las empresas, es poder tener reglas claras con respecto a las garantías de sus productos. A medida que la sociedad utilice más y más productos de software, también irán en aumento los reclamos de aquellos usuarios que se ven afectado por la mala producción de los mismos. Las normas son la organización del derecho natural de defensa. Y es por ello que buenas leyes garantizarán que cada parte tenga en claro cuáles son sus derechos y cuáles sus obligaciones.

Esta es una industria en donde la mano de obra escasea, y por lo tanto muchas empresas o desarrolladores independientes a veces se aprovechan de esa situación reduciendo la calidad de sus productos, total saben que trabajo por muchos años no va a faltar. Buenas leyes ayudarían a reducir ese problema.

Hasta aquí, los beneficios parecen claros. Pero el desafío estará puesto en la adaptación que puedan hacer los organismos competentes de las normas de defensa del consumidor, a la industria del software. Lo cual no es una tarea para nada fácil. Deben tener en cuenta la gran diversidad de factores que pueden afectar al funcionamiento de una aplicación y distinguir en qué momentos es responsable la empresa y en cuáles no. También deben lograr que dichas normas no frenen el gran crecimiento que tiene en la actualidad el sector, ya que muchos de los avances que se producen en esa industria mejoran la vida de millones de personas con mucha facilidad y en poco tiempo. Y por último, su cumplimiento debe estar al alcance de todo tipo de empresas, para no favorecer a las gigantes como tantas veces ha pasado en todo tipo de industrias en la historia de la humanidad.

 

Microsoft vs Google vs El resto del Mundo – Round Junio 2009

Junio 2, 2009 by Miguel Zabala 1 Comment »

Está claro que Microsoft no se da por vencido en cuanto al mercado de los buscadores y la publicidad en ellos se refiere, eso lo demuestra con su nuevo motor de búsqueda Bing. Luego de echarle un vistazo he podido comprobar que esta nueva apuesta de Microsoft tiene unas características interesantes y ahora podríamos decir que sus resultados son más acertados y que cuenta con herramientas que enriquecen la experiencia del usuario como: la pre visualización de videos y sus filtros contextuales que son muy útiles a la hora de redefinir o restringir una búsqueda.

Por otra parte Google disfrutando de su posición dominante en lo que búsquedas se refiere va mas allá presentando Google Wave, que podría ser descripto como una especie de todo en uno de las comunicaciones, aplicando el concepto de waves (olas en español) intenta organizar documentos, imágenes y adjuntos en threads de comunicación. Es un producto que me atrevo a decir que intentará competir con muchas aplicaciones de comunicación, mensajería on line, redes sociales y hasta aplicaciones como Basecamp. Un punto a tener en cuenta es que Google Wave cuenta con una aplicación Servidor que permite instalarlo en servidores propios y tener el control uno mismo de la información, en lo personal no soy amante de almacenar todos los documentos y comunicaciones de mi organización en Google.

Como última apuesta Microsoft acaba de presentar en la E3, la exposición mas importante de juegos a nivel mundial, una idea muy novedosa que dio a conocer como Project Natal; básicamente es una tecnología que combina una cámara de alta resolución que gracias a un software de reconocimiento de movimientos corporales provee una interacción con aplicaciones y juegos de la consola Xbox 360, con esto Microsoft renueva su apuesta y tratará de quitarle el liderazgo a Nintendo con su Wii en controles de mando y juegos que interactúan con el cuerpo humano. Además incluye reconocimiento de voz también para realizar acciones, que espero funcione mejor que la versión de Windows Vista.

Creo que es una tecnología que tiene mucho para dar, y en el futuro esta tecnología podría estar en muchos dispositivos de nuestros hogares permitiéndonos una experiencia muy distinta a la que hoy estamos acostumbrados.

Windows 7 + Bing + Project Natal me parece que Ballmer encontró el camino correcto para Microsoft, mientras Google sigue innovando con proyectos open source y free; realmente me emociona poder presenciar los lanzamientos de estas novedades, analizarlos y criticarlos. Por nuestro lado en ZedPlan estamos trabajando en tecnologías y productos propios que espero usted pueda usar cotidianamente y aporte a sus tareas diarias.

 

Windows, su estabilidad y rendimiento

Mayo 29, 2009 by Miguel Zabala 8 Comments »

Esta claro que no todas las decisiones en compañías como Microsoft se toman para beneficio del usuario. He probado contemporáneamente con la salida de cada una de las versiones de Windows desde el 3.11 hasta el Actual 7 RC. No todos los Windows fueron un éxito y algunos siquiera llegaron a ser un sistema estable y depurado.  Tal fue el caso del bochornoso Windows ME que era totalmente inestable, con el cuál era imposible trabajar. Fue por eso que muchos de nosotros en aquel momento optamos por Windows 98 para jugar o por su compatibilidad de Hardware; o por Windows 2000 para trabajar, el que si bien era menos compatible, era mucho más estable y productivo.

En la actualidad nos encontramos con una situación similar donde tenemos un sistema operativo bien logrado, maduro y estable como lo es Windows XP, y un sistema operativo prácticamente reescrito como lo es Vista, el cual no logra alcanzar mis expectativas de estabilidad y por sobre todo rendimiento.

Es importante destacar que cuando se analiza el rendimiento de cualquier software, el análisis debe hacerse sobre un hardware acorde a la época en que fue lanzado dicho soft. Es injusto para un sistema operativo contemporáneo intentar correrlo con Hardware tan viejo como de hace 3 años, ya que un nuevo sistema implica un diseño de software nuevo, pensando en que se tendrá más recursos del equipo informático. Ésta es una visión que un usuario retail no tiene simplemente porque es ajeno al proceso de diseño del software. Está claro que tanto Windows Vista como Windows 7 fueron pensados para necesitar más potencia del equipo. De todas maneras esto no justifica el tan bajo rendimiento de Windows Vista; necesitar significa que ahora utilizarán mas memoria, más poder de procesamiento y hasta aceleración grafica, ya sea para colocar mas características en el escritorio, cachear ciertos elementos (acelerando en algunas situaciones los accesos a algunas características) o bien para incorporar gadgets innecesarios. Pero esto es así señores, sólo traten de correr hoy en día en un equipo contemporáneo Windows 3.11, con Microsoft Works, simplemente volará, eso no quiere decir que Windows 3.11 sea “mejor” que Windows XP.

Respecto a Windows 7, creo que lograron depurar y optimizar el código base de Windows Vista para lograr un digno reemplazo de Windows XP; claro que puede llegar a funcionar en determinadas situaciones un poco más lento que XP, pero a cambio de nuevas características: como la búsqueda de aplicaciones y documentos incorporadas en el menú inicio, un look and feel mas acorde a nuestros tiempos, una interfaz bien lograda; y claro lo que la mayoría de los usuarios niega pero todos sabemos, a todo geek le gusta tener lo ultimo y los sistemas operativos no son la excepción. Yo por mi parte participo del programa de Microsoft, así que ya estoy utilizando para producir Windows 7 RC y verdaderamente en mi Laptop ha llegado para quedarse.

 

Uso del historial en aplicaciones AJAX cambiando el título del documento dinámicamente

Mayo 23, 2009 by Demián Rodríguez No Comments »

Actualmente podemos encontrar gran cantidad de librerías que faciliten la utilización del historial del navegador para registrar cambios en el estado de la página, pero ninguna de ellas (o al menos las que yo encontré) logran resolver esta situación.

Si estás perdido y no sabes de que estoy hablando, aquí hay un muy buen artículo (en inglés) que explica en detalle como aplicar la técnica del uso del botón atrás/adelante en aplicaciones AJAX.

Detecté el problema mientras desarrollaba el portfolio de ZedPlan. Al seleccionar un proyecto se actualiza la URL, lo cual hace que mediante una solicitud AJAX se obtengan los datos del mismo y se actualice el documento. También me pareció lógico actualizar el título, ya que sino quedará guardado en el historial del navegador el título del documento oiriginal, y sería poco intuitivo para el usuario.

En ese momento noté que en Firefox el historial no estaba sincronizado con el título del documento actual. ¿Por qué?, parece que si cambiamos el título del documento una vez que se guardó la entrada en el historial, el navegador no lo actualiza y debemos aplicar un pequeño hack, el cual consiste en actualizar el hash de la URL nuevamente de la siguiente forma:

window.location.hash = window.location.hash;

Como era de esperarse, en Internet Exporer 6 y 7 tenemos otro problema. Para ver reflejado en el historial el título del documento, debemos cambiarlo en el iframe que se usa como hack, ya que se extrae de la etiqueta <title>. Para esto, al src del iframe le enviamos como parámetro el título del documento junto con el hash. El truco acá es cambiar el título antes de actualizar el iframe, ya que si lo cambiamos con javascript no se va a ver reflejado el cambio en el historial.

Veamos un ejemplo usando la clase HistoryManager, la cual desarrollé hace unos meses y la modifiqué para agregar soporte a los títulos dinámicos. Requiere al framework Prototype, aunque con pocas modificaciones se podría adaptar a otros frameworks como jQuery.

Supongamos que tenemos una página donde tenemos contenido agrupado en tabs, según el tab seleccionado mostramos u ocultamos lo que corresponda, pero guardando en el historial cada cambio de tab para permitir bookmarking.
Al cargar la página ejecutamos la función init():

function init() {
	hm = new HistoryManager(
			update, // callback
			200, 	// intervalo en milisegundos para revisar cambios en el hash
			'/history.php', // URL del documento que se usa como hack para el IE (abajo está el codigo fuente)
			true // habilitar títulos dinámicos, asi debemos llamar manualmente al metodo setTitle() en la función update()
		);
}
/**
 * Esta función se ejecuta cuando hubo cambios en el hash.
 * @param string nuevo hash
 * @param string hash anterior
 */
function update(hash, prev) {
	 // si no hay ni hubo hash no hacemos nada en este caso.
	if (!hash && !prev) return;

	// en este caso el contenido que generamos depende de un id, el cual lo obtenemos del hash
	// por ejemplo, si queremos mostrar un contenido u otro dependiendo de un tab seleccionado
	// el formato del hash podría ser "#tab-1" o "#tab-2"
	var id = hash.split('-').last();

	// establecemos el titulo del documento segun el nuevo contenido
	// acá lo sabemos de antemano, pero sería mas común obtenerlo mediante AJAX segun el id
	if (hash) this.setTitle("Tab " + id); // debería ser mas descriptivo el título!
	else this.setTitle("Home"); // si no hay hash, reestablecemos el titulo original
}

Y el código fuente de history.php

<?
	$hash = json_encode(isset($_GET['hash']) ? $_GET['hash'] : '');
	$title = isset($_GET['title']) ? $_GET['title'] : '';
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title><?=htmlspecialchars($title)?></title>
	<meta name="robots" content="noindex, nofollow" />
	<script type="text/javascript">/*<![CDATA[*/
		hash = <?=$hash?>;
		function update() {
			if (!parent) return;
			parent.location.hash = hash;
		}
	/*]]>*/</script>
</head>
<body onload="update()"></body>
</html>

Esta clase fué probada en Firefox 3, IE 6 & 7, Chrome, Safari 4 para Windows y Opera 9.64.

 

Quizás a Ud. no le convenga trabajar aquí

Mayo 16, 2009 by Javier Guzmán No Comments »

Cada vez que tomo una entrevista, además de contarle a mi entrevistado las virtudes de mi empresa, me aseguro de comunicarle las mayores debilidades y problemas con las que nos enfrentamos a diario.

Muchos piensan que con esta acción estoy achicando las posibilidades de que esa persona acepte ingresar a la empresa (de hecho, lo he tenido que discutir con antiguos jefes), sin embargo, la realidad siempre me mostró claros beneficios:

- Le demostramos al postulante que en nuestra empresa somos sinceros, que la comunicación cuando esté trabajando con nosotros será realmente franca y abierta.

- Mostramos que somos conscientes de nuestros problemas, y estamos trabajando para resolverlos.

- Le permitimos al interesado en el puesto, que haga un análisis correcto acerca de si sus capacidades son compatibles o no con nuestra organización. Gran parte de este análisis lo harán en la misma entrevista, intercambiando opiniones con el “entrevistador sincero

- Alentamos a que el postulante se sincere acerca de sus propias debilidades. Es increíble ver como las personas dejan de estar a la defensiva al ver que enfrente tienen a una persona que se maneja con la verdad.

Tras varios años de comunicarle a mis entrevistados que mi empresa no es perfecta, que quizás a él o ella no le conviene trabajar con nosotros, siempre he obtenido muy buenos resultados. Por lo tanto, no piense que espantará a su postulante, sino que por el contrario, lo más probable es que quiera trabajar con usted.