Zona HTML Zona Java Zona PHP Zona ASP Zona Bases de datos
Inicio > Tutoriales > Internet > PHP > LiveChat – Jabber en nuestra aplicación web
-Tutoriales

LiveChat – Jabber en nuestra aplicación web


Regreso a clases, o cómo pasar lista de asistencia

Antes de mostrar de qué manera es posible verificar el estado de disponibilidad de un usuario dado, debemos explicar algunos de los mecanismos que rigen la red Jabber. Una de sus reglas fundamentales es la de protección de la privacidad de todos y cada uno de sus participantes, por lo que no es posible conocer la disponibilidad de otra persona sin que ésta tenga de ello conocimiento y lo haya aprobado previamente.

Para poder estar al corriente de la presencia de otros participantes de la red, es necesario enviar un comunicado del tipo adecuado solicitando permiso para hacerlo. El usuario en cuestión puede, por supuesto, dar o no su consentimiento. La mayoría de los clientes Jabber pueden ser configurados para que, junto con la aceptación propia, se envíe una solicitud de observación del estado de su remitente. De esta manera se crean relaciones recíprocas, en las que dos usuarios son informados de sus respectivas entradas y salidas de la red.

El estado de un usuario puede tener como mínimo uno de los dos valores existentes: disponible y no disponible. El estado no disponible no es especialmente interesante: significa que un usuario dado no está presente en la red. Por otra parte, resulta que es posible estar disponible en mayor o menor medida. Estas diferencias en el estado de disponibilidad permiten al potencial interlocutor saber si en un momento dado estamos demasiado ocupados para conversar o si, al contrario, podemos charlar libremente.

Utilizando un cliente Jabber podemos declarar que estamos:

  • disponibles
  • disponibles y dispuestos a chatear (ing. free for chat)
  • temporalmente lejos del ordenador (ing. temporarily away)
  • ausentes por un periodo más bien largo (ing. extended away)
  • ocupados y pedimos que no se nos moleste (ing. do not disturb)

En el protocolo estos estados son representados, respectivamente, por los siguientes códigos: [vacío], chat, away, xa, dnd.

El intercambio de paquetes con estados de disponibilidad puede tener lugar en dos situaciones diferentes:

  • inmediatamente después de que un usuario ingrese a la red el servidor le envía una lista (conocida como roaster) con el estado de cada uno de sus contactos,
  • todo cambio de estado de un usuario hace que el servidor envíe una notificación de este hecho a todos los demás usuarios en cuyas listas de contacto éste se encuentre.

Esto implica que existan dos modos diferentes de obtener información sobre la disponibilidad de un usuario: podemos preguntar directamente al servidor acerca de todos los usuarios de nuestra lista (simplemente iniciando una nueva sesión), o esperar a que el servidor nos notifique los cambios de estado que vayan ocurriendo entre nuestros contactos.

Desafortunadamente, ambos modelos tienen sus desventajas desde el punto de vista del programador web. La apertura de una nueva sesión de Jabber es una operación que requiere de mucho tiempo, por lo que una página con la lista de contactos cuyo funcionamiento se base en este método podría terminar siendo inaceptablemente lenta. La opción de esperar notificaciones del servidor tampoco parece ser una salida viable, puesto que una vez visualizada la página web, el entorno PHP desaparece y no queda ningún proceso que pueda recibir la información.

Pero existe una manera elegante de resolver estos dos problemas: lanzar desde la consola (en segundo plano, en el servidor web) un proceso independiente de PHP que se ocupe de mantener la comunicación con la red Jabber. De esta manera podemos simular un verdadero cliente que esté continuamente en la memoria y sea capaz de almacenar los resultados de su trabajo en una base de datos. Un cliente así puede ser utilizado por otros scripts del lado del servidor, los cuales serán capaces de hacer uso de las informaciones provenientes de la red Jabber sin necesidad de interactuar directamente con ella. La arquitectura de una solución como la expuesta ha sido presentada en la Figura 2.

Figura 2: Arquitectura de la solución basada en un script lanzado desde la consola

. El programa lanzado desde la consola

Todas estas consideraciones teóricas pueden parecer demasiado amplias, pero son indispensables para poder analizar y entender el script del Listado 2.

Listado 2: Recepción de información sobre los estados de disponibilidad
<?php

require('lib/jabber/class.jabber.php');

$JABBER = new Jabber;

$JABBER->server        = 'localhost';
$JABBER->port           = '5222';
$JABBER->username       = 'www_send';
$JABBER->password       = 'www_send';
$JABBER->resource       = 'ClassJabberPHP';

$JABBER->Connect() or die('¡No puedo conectarme!');
$JABBER->SendAuth() or die('¡No puedo autorizarme!');

$JABBER->SendPresence();
$JABBER->CruiseControl();
$JABBER->Disconnect();

function Handler_presence_available($message) {
    global $JABBER;
    $jid = $JABBER->StripJID($JABBER->GetInfoFromPresenceFrom($message));
    $status = $JABBER->GetInfoFromPresenceShow($message);

    print "$jid - status: $status";
}

function Handler_presence_unavailable($message) {
    global $JABBER;
    $jid = $JABBER->StripJID($JABBER->GetInfoFromPresenceFrom($message));
    $status = $JABBER->GetInfoFromPresenceShow($message);

    print "$jid - status: $status";

}

?>

En este listado pueden verse muchos de los elementos que ya conocemos: el establecimiento de la conexión con el servidor, la autorización... En realidad, la única “novedad” es la invocación del método $JABBER->CruiseControl() y la definición de dos nuevas funciones: Handler_presence_available($message)Handler_presence_unavailable($message).

Los nombres de las nuevas funciones indican claramente cuál es su uso: las llama la clase ClassJabberPHP en respuesta a ciertos comunicados recibidos de la red Jabber (en concreto a los que contienen información acerca del estado de disponibilidad de otros usuarios). El método CruiseControl() es una manera de decir “desde este momento escucha y si aparece algún comunicado, invoca la función apropiada (ing. handler) para el manejo del tipo de comunicado recibido”.

Una vez las informaciones sobre el estado de disponibilidad de los usuarios que nos interesan se encuentran en la base de datos, la creación de un script que nos permita visualizarlas no representa para nosotros mayor problema.

. Recepción de mensajes

Nuestro programa sabe ya hablar (puede enviar mensajes – Listado 1) y ver (puede observar los estados de otros usuarios – Listado 2). De la conversación plena nos separa sólo un paso: la posibilidad de escuchar. Se trata de una tarea bastante sencilla si recordamos la manera en que leíamos las informaciones acerca de los estados de disponibilidad: en este caso también debemos crear una función-handler que se encargue de recibir los comunicados de tipo mensaje (ing. message). El fragmento de código presentado en el Listado 3 es bastante ilustrativo de cómo se hace esto en la práctica.

Listado 3: Función-handler para el manejo de mensajes de tipo chat
...
function Handler_message_chat($message) {
   global $db;
   global $JABBER;

   $msg = $JABBER->GetInfoFromMessageBody($message);
   $thread = $JABBER->GetInfoFromMessageThread($message);
   $sql =
      'INSERT INTO jabber_messages (sid, msg)
       VALUES ("'.$thread.'", "'.$msg.'")';

   if (!$db->Execute($sql)) {
      die ('Error de acceso a la base de datos!');
   }
}
...

Nótese cómo el mensaje recibido se introduce inmediatamente en la base de datos (igual que como lo hicimos con la información sobre la disponibilidad), por lo que el script para visualizar mensajes en una página web resulta muy sencillo de escribir y es totalmente independiente de los servicios Jabber. Además, esto nos permite conservar el historial completo de las conversaciones realizadas.

 
Patrocinados
 

Copyright © 1999-2006 Programación en castellano. Todos los derechos reservados.
Formulario de Contacto - Datos legales - Publicidad

Hospedaje web y servidores dedicados linux por Ferca Network