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


Aún somos demasiado pocos

Dado que la comunicación bidireccional y la verificación del estado de disponibilidad de un usuario en la red Jabber no es ya para nosotros ningún problema, pongámonos manos a la obra y construyamos una aplicación completa que permita a múltiples usuarios de Internet comunicarse con varios empleados (consultores). Hasta este momento habíamos estudiado solamente el caso de un solo usuario que se comunica con un solo consultor, que es una situación raramente encontrada en aplicaciones reales.

Nuestro plan de acción será el siguiente:

  • el cliente visualiza la página con los contactos,
  • en la página aparece la lista de los consultores disponibles en ese momento (está claro que esta lista puede estar vacía, en cuyo caso el cliente deberá esperar un momento),
  • si alguno de los consultores está disponible, el cliente puede iniciar con él una conversación,
  • una vez iniciada la conversación, el consultor desaparece de la lista de empleados disponibles y el cliente puede conversar sin interrupciones con la persona elegida.

El esquema de navegación para las páginas web y la arquitectura de la aplicación completa se muestran en la Figura 3.

Figura 3: Esquema de navegación y arquitectura de la aplicación

Como podemos ver, múltiples usuarios virtuales hacen uso de una misma cuenta en la red Jabber. Debido a esto, se hace necesario un mecanismo que permita redireccionar los mensajes enviados por el consultor a un usuario determinado.

. El atributo thread

Como recordaremos, todo mensaje puede poseer el atributo opcional thread, que permite distribuir los mensajes enviados y recibidos en hilos lógicos de conversación sobre un tema dado. La especificación del protocolo establece que un cliente Jabber, después de haber recibido un mensaje con este atributo, debería:

  • añadir a cada respuesta dada al mensaje el identificador del hilo de conversación obtenido como valor del atributo,
  • ofrecer al usuario una interfaz que permita distinguir entre los diferentes hilos de conversación, incluso cuando varios de ellos han sido realizados con el mismo usuario.

Pensemos un momento: si enviamos desde la página web un comunicado que contenga el atributo thread, en cuyo valor se encuentre el identificador de la sesión PHP, las respuestas del consultor también contendrán en su campo thread el identificador de sesión PHP. ¡Bingo! Esto nos permitirá diferenciar las preguntas hechas por diferentes usuarios de nuestro formulario a un mismo consultor.

Existe, desgraciadamente, un pequeño problema: Jabber es un protocolo bastante joven y no todas sus implementaciones están completamente conformes con la especificación. En particular, en algunas soluciones el atributo thread es completamente ignorado, lo que evidentemente imposibilita el uso de la idea presentada más arriba. Sin embargo, no es cuestión de preocuparse demasiado por anticipado, puesto que también existen productos que implementan correctamente el protocolo, tales como Exodus, el cual ofrece todas las funciones estándar de un cliente de mensajería instantánea, además de una buena documentación.

. Estoy ocupado

El último problema que debemos resolver para que nuestra aplicación sea una herramienta realmente útil es el de la asignación de un usuario de la web (o sea, de su número de sesión) a un consultor determinado. Para resolverlo, supondremos que la sesión se desarrollará de la siguiente manera:

  • el consultor llega a su trabajo, arranca su cliente de mensajería instantánea y cambia su estado de disponibilidad a chat, dando a saber de esta manera que está listo para responder a las preguntas de los usuarios,
  • la información acerca de la disponibilidad del consultor se introduce en la base de datos de la aplicación,
  • el usuario visita la página web con la lista de consultores disponibles y selecciona uno de ellos para iniciar una conversación,
  • en la base de datos de la aplicación anotamos que el usuario de número de sesión PHP tal se ha conectado con el consultor de identificador JID tal. Cambiamos el estado (en la base de datos) de este consultor a no disponible,
  • el consultor obtiene el primer mensaje del usuario web. Puesto que espera estar ocupado con esta conversación por algún tiempo, cambia su estado de disponibilidad a “no molestar” (dnd),
  • ambas partes conversan sirviéndose cada una de su propia interfaz de usuario,
  • cada una de las partes puede finalizar la conversación. Del lado del usuario, esto se realiza haciendo clic sobre un enlace determinado. El consultor debe cerrar la ventana en la que se ha llevado a cabo la conversación (¡muy importante!) y cambiar su estado de disponibilidad a chat,
  • cuando una de las partes pone fin a la conversación, la entrada de la base de datos que señalizaba la existencia de una relación entre la sesión PHP y el JID es automáticamente eliminada.

Observemos ahora cómo podemos poner este plan a la práctica. El Listado 4 muestra la parte (modificada) de la aplicación de consola, la cual hace uso repetido de dos clases: JabberConsultants y JabberMessages, cuyas definiciones pueden verse en los Listados 5 y 6 al final del artículo.

Listado 4: Script lanzado desde la consola – console.php
<?php
/**
  * @package jabber.console
  */

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

require('class/model/JabberConsultants.php');
require('class/model/JabberMessages.php');

$jmessages = new JabberMessages($db);
$jconsultants = new JabberConsultants($db);

$jconsultants->setAllUnavailableStatus();

$JABBER = new Jabber;

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

print "Conectándose con el servidor $JABBER->server ...     ";
$JABBER->Connect() or die('¡Ha sido imposible establecer la conexión!');
print "¡la conexión ha sido correctamente establecida!\n";

print "Autorizando al usuario $JABBER->server ...     ";
$JABBER->SendAuth() or die('¡No ha sido posible autorizar al usuario!');
print "¡autorización correctamente realizada!\n";

print "Listo para enviar y recibir mensajes...\n";
$JABBER->SendPresence();

while(1) {
   $JABBER->CruiseControl(10);
   $msg_array = $jmessages->getMessagesForSend();

   foreach ($msg_array as $msg_to_send) {
      print "Enviando un mensaje a ".$msg_to_send['jid']."... \n";
      $JABBER->SendMessage($msg_to_send['jid'],"chat",NULL,
         array(
            "thread" => $msg_to_send['sid'],
            "body" => $msg_to_send['msg']
         )
      );

      $jmessages->markAsSend($msg_to_send['msg_id']);
   }
}

$JABBER->Disconnect();

function Handler_message_chat($message) {
   global $JABBER;

   $msg = $JABBER->GetInfoFromMessageBody($message);
   $sid = $JABBER->GetInfoFromMessageThread($message);

   if ($sid!='') {
      global $jmessages;
      $jmessages->sendMsgFromConsultant($sid,$msg);
   }
}

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

    global $jconsultants;
    $jconsultants->setAvailableStatus($jid,1,$status);
}

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

    global $jconsultants;
    $jconsultants->setAvailableStatus($jid,0,null);
}

?>

El proceso completo de comunicación se muestra en la Figura 4.

Figura 4: Proceso de conversación con el consultor

Se hacen aquí necesarias algunas aclaraciones acerca del código presentado. No hemos hecho aún mención del uso que hace éste de ADOdb como su capa de abstracción para el acceso a la base de datos. Gracias a ésto no tenemos que preocuparnos por el problema de la dependencia de un tipo concreto de la base.

Notemos también la manera en que se envían los mensajes nuevos: primero se introducen en la base de datos, y después, con ayuda del script console.php, se transmiten a la red Jabber. Esta solución tiene dos ventajas fundamentales: por un lado podemos conservar el historial de la comunicación completa y, por el otro, el script console.php es el único (!) en toda la aplicación que sabe de la existencia de la clase que implementa el protocolo Jabber. Esto hace sencilla la sustitución de esta clase por otra, o incluso, el uso de una red de mensajería instantánea completamente diferente.

 
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