UNIVERSIDAD DE CHILE FACULTAD DE CIENCIAS FÍSICAS Y MATEMÁTICAS DEPARTAMENTO DE CIENCIAS DE LA COMPUTACIÓN ADMINISTRACIÓN DE SERVICIOS Y PERFILES DE USUARIO, EN APLICACIONES COLABORATIVAS MÓVILES MEMORIA PARA OPTAR AL TÍTULO DE INGENIERO CIVIL EN COMPUTACIÓN CLAUDIO ANDRÉS OYARZÚN SORIC PROFESOR GUÍA: SERGIO OCHOA DELORENZI MIEMBROS DE LA COMISIÓN: GABRIEL IRIBARREN RÍOS JOSÉ PINO URTUBIA SANTIAGO DE CHILE AGOSTO 2007 Resumen El objetivo general de este trabajo de título es diseñar e implementar dos soluciones de software que están directamente interrelacionadas. La primera sirve para administrar servicios Web y la segunda administra perfiles de sus usuarios en aplicaciones colaborativas, las cuales ejecutan sobre redes MANETs (Mobile Ad-hoc NETworks). Específicamente estas aplicaciones son un administrador de servicios y un administrador de perfiles de unidades móviles. Ambas soluciones forman parte de un middleware que tiene por finalidad servir de plataforma de interacción para aplicaciones colaborativas móviles. Actualmente los servicios Web son ampliamente utilizados por aplicaciones de software, debido principalmente a la masiva utilización de Internet (e Intranets) como herramienta de trabajo, y la necesidad de interoperar entre distintas soluciones. Actualmente la mayoría de las soluciones que emplean estos servicios Web, involucran redes cableadas o bien redes inalámbricas con alta estabilidad de señal. Sin embargo, esto no es el escenario en el cual realizan sus actividades los trabajadores móviles, los cuales necesitan comunicarse con sus pares para intercambiar datos o colaborar en escenarios de escasa o nula conectividad. Para facilitar las actividades de estas personas, se construyó un administrador de servicios Web que permite organizar las peticiones de servicio realizadas por las distintas unidades móviles. Esto se hace mediante una cola que retiene las solicitudes durante los periodos de desconexión, y que además permite hacer un registro persistente de ellas cuando la aplicación se cierra. También se desarrolló un sistema de administración de perfiles, el cual permite identificar las características del dispositivo que ejecuta aplicaciones basadas en el middleware. En base a ello, la aplicación adapta su comportamiento según las prestaciones de la máquina donde ejecuta y el perfil del usuario. Finalmente se integraron estos dos sistemas a los componentes existentes del middleware, probando su funcionamiento con una aplicación diseñada específicamente para ello. El resultado final del desarrollo fue un middleware que posibilita la utilización de servicios Web en entornos donde la conectividad no está garantizada, facilitando así el trabajo colaborativo y la posibilidad de compartir recursos entre pares. Esto último fue evaluado con especial cuidado con la realización de un test de stress sobre el traspaso sucesivo de archivos. Los resultados obtenidos fueron satisfactorios, indicando tiempos de respuesta aceptables para los contextos identificados. Allí las bajas prestaciones de algunos dispositivos móviles no representan una amenaza para el correcto desempeño del middleware. Este middleware constituye una estructura de apoyo que posibilita a los usuarios de dispositivos móviles pasar de ser simples usuarios “en movimiento”, que realizan sus labores diarias y centralizan sus datos y avances en determinados momentos de la jornada, a trabajadores móviles que no dependen de la infraestructura de red para colaborar. En este caso, según la disponibilidad de redes físicas o compañeros con los cuales interactuar, estos trabajadores móviles pueden compartir recursos, realizar actividades en conjunto o simplemente hacer trabajo individual. 2 Agradecimientos Quiero agradecer al profesor Sergio Ochoa por el apoyo que me brindó durante el desarrollo de este trabajo, el cual fue fundamental en la consecución correcta y a tiempo de los objetivos de la memoria. Agradezco también a Andrés Neyem por su notable ayuda y excelente disposición a colaborar con mi trabajo. Finalmente, no puedo dejar de mencionar a mi familia, que me ha entregado su apoyo incondicional durante estos años de estudio. En especial quiero agradecer a mis padres, Maritza y Ramón, por sus infinitas muestras de afecto y comprensión, y por estar junto a mí siempre que lo he necesitado, ya que sin ellos me habría sido imposible llegar hasta donde he llegado. 3 Índice 1. Introducción...........................................................................................................................................7 1.1. Funcionamiento de la Arquitectura ...........................................................................................8 1.2. Justificación del Trabajo..............................................................................................................9 1.3. Objetivos de la Memoria.......................................................................................................... 10 1.4. Revisión Bibliográfica ............................................................................................................... 11 1.4.1. Colaboración Móvil ......................................................................................................... 11 1.4.2. Compartir Recursos entre Pares .................................................................................... 13 2. Diseño e Implementación................................................................................................................. 15 2.1. Proyectos Base para el Administrador de Servicios Web.................................................... 15 2.1.1. Clientes Inteligentes......................................................................................................... 15 2.1.2. Smart Client Offline Application Block (SCOAB) ..................................................... 15 2.1.3. OpenNETCF Application Blocks 1.0 (OpenAB)....................................................... 18 2.1.4. Evaluación de Rendimiento............................................................................................ 19 2.2. Administrador de Servicios (Service Manager) ..................................................................... 20 2.2.1. Estructura Principal ......................................................................................................... 20 2.2.2. Elección de Proveedor de Almacenamiento ................................................................ 26 2.2.3. Mecanismos de Persistencia de la Cola......................................................................... 30 2.3. Administrador de Perfiles de Unidades Móviles (Mobile Units Profile Manager) .......... 31 2.3.1. Descripción del Perfil de una Unidad ........................................................................... 32 2.3.2. Sistema de Roles............................................................................................................... 33 3. Descripción de la Aplicación Desarrollada..................................................................................... 35 3.1. File Sharing Test ................................................................................................................... 35 3.2. Integración al Middleware ................................................................................................... 37 4. Resultados Obtenidos........................................................................................................................ 39 5. Conclusiones y Trabajo a Futuro..................................................................................................... 41 6. Bibliografía .......................................................................................................................................... 43 Apéndice A. Código Fuente ...................................................................................................................... 46 A1. Infraestructura Offline.................................................................................................................... 46 A2. Proveedores de Almacenamiento.................................................................................................. 54 A3. Administrador de Perfiles............................................................................................................... 58 4 Índice de Figuras Figura 1. Arquitectura del middleware ................................................................................................................8 Figura 2. Interacción entre aplicaciones móviles a través del middleware.....................................................9 Figura 3. Enfoques para manejo de desconexiones.................................................................................... 16 Figura 4. Relación entre elementos de una infraestructura offline.............................................................. 17 Figura 5. Arquitectura del SCOAB................................................................................................................ 18 Figura 6. Estructura de un Payload ............................................................................................................... 21 Figura 7. Estructura del QueueManager....................................................................................................... 22 Figura 8. Estructura del OfflineBlockBuilder.............................................................................................. 23 Figura 9. Estructura de un ServiceAgent genérico...................................................................................... 24 Figura 10. Estructura de un delegado y un evento de ejemplo ................................................................. 24 Figura 11. Flujo de una petición de servicio ................................................................................................ 25 Figura 12. Estructura del QueueStorageProvider y las interfaces que implementa ............................... 26 Figura 13. Estructura del ProfileManager .................................................................................................... 31 Figura 14. Ejemplo de relaciones jerárquicas entre roles de usuario........................................................ 33 Figura 15. Estructura del servicio FileSharingMobileService .................................................................... 35 Figura 16. Interfaz gráfica (GUI) de File Sharing Test............................................................................... 36 Figura 17. Interfaces de muestra de integración del middleware ................................................................. 38 5 Índice de Tablas Tabla 1. Tiempo de respuesta [s] de un servicio web con y sin SCOAB................................................. 20 Tabla 2. Comparación técnica de servidores................................................................................................ 27 Tabla 3. Tiempo de respuesta [s] de un servicio corriendo sobre IIS...................................................... 28 Tabla 4. Tiempo de respuesta [s] de un servicio corriendo sobre el MicroWebServer en un PC........ 29 Tabla 5. Tiempo de respuesta [s] de un servicio corriendo sobre el MicroWebServer en PocketPCs 30 Tabla 6. Tiempo de respuesta [s] de un servicio corriendo sobre una PocketPC Dell sin Service Manager ............................................................................................................................................................. 30 Tabla 7. Comparación Técnica de Dispositivos.......................................................................................... 39 Tabla 8. Tiempo de respuesta [s] de traspasos sucesivos entre distintos tipos de servidores y clientes ............................................................................................................................................................................ 40 6 1. Introducción Los avances en la comunicación inalámbrica y la informática móvil extienden los escenarios de colaboración. La estrategia actual para abordar diversos problemas productivos, educativos y sociales consiste en incorporar a los trabajadores móviles el uso de dispositivos computacionales inalámbricos en las prácticas cotidianas de trabajo. Un trabajador móvil es concebido como una persona que está en continuo movimiento y que ejecuta tareas en cualquier lugar y en cualquier momento; por lo tanto, el uso de dispositivos de computación móvil para apoyar sus actividades podría ser de gran ayuda. Esta cualidad de los trabajadores móviles (la de llevar consigo sus actividades mientras están en movimiento), generalmente ocasiona instancias en las cuales deben sincronizar sus datos o colaborar con otras personas. Los trabajadores móviles frecuentemente no tienen certeza de cuál será el próximo escenario físico en el cual se encontrarán, ni de sus características. Por lo tanto, ellos necesitan de soluciones flexibles y autónomas. Esto significa que cuando dos o más trabajadores móviles se reúnen, el escenario físico donde están ubicados no puede ser una limitante para colaborar. Actividades de colaboración que involucran trabajadores móviles usualmente son soportadas por redes móviles llamadas MANETs (Mobile Ad-hoc NETworks) [Macker, 1998]. Sin embargo, el soporte de estas actividades en MANETs implica encontrar soluciones de diseño específicas para este tipo de escenario. La mayoría de las infraestructuras de software conocidas que dan soporte a la colaboración entre trabajadores móviles, constan de algún tipo de centralización de datos y de servicios, pues consideran a la infraestructura de comunicaciones como estable. Esta situación restringe las posibilidades de colaboración, particularmente en escenarios de comunicación ad-hoc. Por lo tanto, se necesitan implementar soluciones totalmente distribuidas para poder abarcar este nuevo escenario de comunicaciones inestables, como lo son las redes ad-hoc. Esta memoria está enfocada en proveer soluciones que brinden soporte a actividades de colaboración entre trabajadores móviles en redes MANETs. Concretamente, se han desarrollado dos componentes de un middleware que se ejecutará en laptops, tablet PC y PDAs; y que será capaz de proveer y consumir servicios de otros dispositivos de computación móviles. Estas componentes corresponden a un administrador de servicios (Service Manager) y un administrador de perfiles de unidades móviles (Mobile Units Profile Manager). El middleware se completa con un micro-servidor Web capaz de ejecutar servicios Web y solicitudes HTTP (MicroWebServer) y un detector de presencia de dispositivos móviles en la red (MUNMe) (Figura 1). Las aplicaciones móviles desarrolladas con este middleware serán capaces de interactuar entre ellas en cualquier escenario de colaboración móvil. 7 Mobile Collaborative Applications API Middleware Local Storage Web Services Shared Files Html Jpeg Gif MicroWebServer Mobile Units Units Profiles Profile Manager Mobile Units Near Me Work Items Queue SOAP Component HTTP Component Service Manager Listener TCP/IP Multicast Figura 1. Arquitectura del middleware 1.1. Funcionamiento de la Arquitectura De la arquitectura anteriormente descrita, se detallan a continuación sus componentes más importantes para el desarrollo de este trabajo de título: 1. Administrador de servicios (Service Manager): Se encarga de recibir las solicitudes de uso de servicios por parte de las distintas unidades móviles, crea y mantiene una cola con las distintas solicitudes recibidas, y coordina la actividad entre las otras componentes del middleware. 2. Administrador de perfiles de unidades móviles (Mobile Units Profile Manager): Su función es manejar los datos correspondientes a las distintas unidades móviles que interactúan, para así proveer de datos de entrada a los distintos servicios web que utilizarán esta plataforma. 3. Detector de presencia de dispositivos móviles en la red (Mobile Units Near Me): Es un módulo cuya función es detectar la presencia de unidades móviles en el radio de conectividad inalámbrica que posee la unidad que se está utilizando. Este componente fue desarrollado en el trabajo de título de otro alumno, por lo cual solo fue necesaria su adaptación e incorporación al middleware y no un desarrollo desde cero. 4. Micro-Servidor web (MicroWebServer): Se encarga de recibir las invocaciones enviadas por el administrador de servicios, activar los servicios y enviar sus resultados. Este componente también fue desarrollado previamente, por lo cual solo fue necesaria su adaptación e incorporación al middleware. 8 Con estos componentes descritos se puede explicar el funcionamiento de la arquitectura mediante un ejemplo, el cual se encuentra gráficamente descrito en la Figura 2: 1. La aplicación A solicita un servicio que está alojado en la aplicación B; 2. Un administrador encola la solicitud del servicio; 3. El administrador verifica que el dispositivo móvil que ejecuta la aplicación B esté en la red móvil; 4. El administrador ejecuta la solicitud del servicio; 5. La solicitud de ejecución de un cierto servicio es recibida por el micro servidor web; 6. El micro servidor web ejecuta el servicio solicitado y 6.1. retorna la información a quien solicitó el servicio, 6.2. o dispara un evento de fin de ejecución de solicitud de servicio a la aplicación B; 7. La información retornada por el servicio solicitado es encolada; 8. La aplicación A obtiene la información del servicio a través del administrador. Aplicación Colaborativa Móvil “A” 1 Aplicación Colaborativa Móvil “B” 6.2 8 6 Manager 2 7 6.1 MicroWebServer 3 4 5 Middleware Middleware Web Services MUNMe MUNMe TCP/IP Multicast Figura 2. Interacción entre aplicaciones móviles a través del middleware 1.2. Justificación del Trabajo Actualmente los servicios Web son ampliamente utilizados por aplicaciones de software, para la solución de problemas de cualquier índole. Esto se debe principalmente, a la masiva utilización de Internet (e Intranets) como herramienta de trabajo. La adopción de sus estándares se hace con mayor facilidad y rapidez cada día, lo que convierte a estos servicios en un nicho de explotación de mucha 9 riqueza. Hoy por hoy, la mayoría de las soluciones que emplean estos servicios Web, involucran redes cableadas o bien redes inalámbricas con alta estabilidad de señal. Esto permite tener conexión (potencialmente) permanente entre el proveedor y el consumidor de un servicio. Sin embargo, esto no es el escenario en el cual realizan sus actividades los trabajadores móviles. Típicamente, estos usuarios trabajan en escenarios muy variados, por lo tanto no es correcto asumir que tendrán redes disponibles todo el tiempo para poder realizar sus actividades. Este nuevo escenario abre un espacio para el diseño de nuevas soluciones que permitan a los servicios Web trabajar, tanto en forma sincrónica, como asincrónica, dependiendo del contexto de trabajo del usuario móvil. Para apoyar la colaboración entre estos usuarios móviles, podemos contar con un tipo de red poco utilizada, pero especialmente diseñada para este tipo de escenarios, la cual es conocida como red móvil ad-hoc. Estas redes permiten que cada trabajador móvil pueda comunicarse con sus pares o con un proveedor de servicios, una vez que ambos se encuentran dentro de un umbral de comunicación, sin necesidad de contar con infraestructura de comunicaciones preexistente. De esa manera es posible que cada usuario ofrezca y consuma servicios; por ejemplo, para compartir su información con sus pares donde quiera que se encuentren. Esto abre posibilidades de aplicaciones basadas en servicios Web que apoyen el trabajo en terreno, por ejemplo: varios veterinarios trabajando en una granja sin acceso a una red, construcciones camineras en sitios apartados, trabajadores de viñas, ventas de parcelas in situ, etc. Las posibilidades son innumerables, están a nuestro alcance y se pueden explotar. El desarrollo de un middleware que brinde soporte a aplicaciones basadas en servicios Web por medio de redes ad-hoc no sólo es un proyecto interesante y ambicioso, sino también uno útil, con múltiples mercados de aplicación y con un gran futuro por delante. El objetivo perseguido en esta memoria es la generación de dos soluciones reutilizables (un administrador de servicios y un administrador de perfiles), que abordan aspectos de diseño típicos de las aplicaciones colaborativas móviles, pero que funcionen para escenarios de trabajo basados en redes MANETs. Ésta es un área nueva, en la cual hay mucho por investigar y proponer. 1.3. Objetivos de la Memoria El objetivo general de esta memoria es diseñar e implementar dos soluciones de software para administrar servicios Web y perfiles de sus usuarios en aplicaciones colaborativas que ejecutan sobre redes MANETs. Específicamente éstas son: un administrador de servicios y un administrador de perfiles de unidades móviles. Estas soluciones formarán parte del middleware anteriormente descrito y servirán para brindar el apoyo necesario para el funcionamiento de aplicaciones colaborativas móviles. Los objetivos específicos que derivan del objetivo general son los siguientes: 1. Diseñar e implementar un administrador de servicios Web, capaz de funcionar sobre redes móviles ad-hoc (MANETs), que posibilite encolar solicitudes de servicios, verificar la presencia de otros dispositivos en la red y distribuir la información entregada por los servicios a sus solicitantes. Esto permitirá que una aplicación colaborativa móvil pueda trabajar como una unidad autónoma. 10 2. Diseñar e implementar un administrador de perfiles de dispositivos móviles, que permita verificar estados y recolectar datos de las distintas unidades que frecuentan las MANET. Esta solución hará posible ajustar el formato de respuesta de un servicio Web según el tipo de dispositivo que invoque el servicio. 3. Integrar las soluciones obtenidas a los componentes existentes del middleware (Mobile Units Near Me y MicroWebServer). 1.4. Revisión Bibliográfica Debido al avance de las comunicaciones inalámbricas y la computación móvil, muchos investigadores y empresas tecnológicas han invertido un esfuerzo importante en tratar de transformar esta oportunidad en un nicho de mercado, o en una nueva rama de soluciones de software. A continuación se presentan los trabajos relacionados más relevantes en el área de colaboración móvil y de sistemas para compartir archivos en redes peer-to-peer. 1.4.1. Colaboración Móvil Entre los framework más importantes de apoyo al desarrollo de aplicaciones colaborativas móviles están los siguientes: • iClouds: Proyecto de la University of Technology of Darmstadt (Alemania), el cual proporciona una arquitectura para interacción de usuarios móviles de manera espontánea, colaborativa y transparente [Heinemann, 2003]. Esta arquitectura provee distintos modelos de comunicación los cuales se basan en el uso de la redes MANET. • JXTA: Iniciativa de Sun que presenta una serie de protocolos abiertos para desarrollar aplicaciones colaborativas en distintas plataformas y dispositivos, desde teléfonos celulares y PDAs hasta PCs y servidores, en el estilo de los protocolos P2P tradicionales. Sus objetivos son lograr interoperabilidad entre sistemas y comunidades P2P, independencia de plataforma (Java) y ubiquidad [Jxta, 2006]. • PASIR: Proyecto desarrollado durante varios semestres en el ramo Ingeniería de Software de nuestro departamento, con el cual se pretendió construir un ambiente ligero de colaboración mediante el intercambio de datos de trabajo y conversación en tiempo real (chat) [Neyem, 2005]. • STEAM: Middleware especializado en el manejo de eventos en escenarios distribuidos, donde la localización juega un rol importante [Meier, 2003]. Este middleware está diseñado para ser usado sobre MANETs, y soporta filtrado de notificaciones de eventos en base a contenido y proximidad. Los filtros por contenido están asociados a políticas personales que cada usuario configura. Los filtros por proximidad apuntan a restringir la propagación innecesaria de eventos dentro de una MANET. Los filtros basados en contenido y en proximidad pueden ser asociados a un productor de eventos, y el único filtro que puede ser aplicado a un consumidor de eventos es el de contenido. 11 • M2MI (Many-to-Many Invocation): Esta plataforma implementa mecanismos de seguridad sobre aplicaciones cooperativas que se ejecutan en redes con una infraestructura fija o móvil de comunicaciones [Bischof, 2003]. M2MI se instala sobre el protocolo de comunicación utilizado y provee administración de seguridad, descubrimiento e invocaciones de métodos de objetos. Además, M2MI usa proxys dinámicos (stubs & skeletons) para crear invocaciones a métodos remotos de forma automática en tiempo de ejecución. Desafortunadamente, esta plataforma utiliza la difusión masiva (broadcasting) como su única estrategia de comunicación, lo cual reduce su aplicabilidad en MANETs. Además, el uso de proxys dinámicos podría hacer que las soluciones implementadas utilizando la plataforma, tengan problemas de rendimiento si son ejecutadas en dispositivos con escasos recursos (memoria y CPU), como por ejemplo en PDAs. • iMAQ (The Integrated Mobile Ad-hoc QoS Framework): iMAQ es un framework que posee una arquitectura cross-layer especializada en la transmisión de multimedia sobre MANETs [Chen, 2002]. Este framework está compuesto por una capa de comunicación (adhoc routing layer) y un middleware que provee servicios a aplicaciones distribuidas. Cada nodo móvil, posee estas dos capas para colaborar y compartir información para proveer calidad de servicio (QoS) sobre el tráfico multimedia. La capa de comunicación facilita un protocolo de ruteo predictivo de QoS basado en localización. El middleware utiliza los servicios provistos por la capa de comunicación para ofrecer a las aplicaciones satisfacción de QoS, información de localización, predicción de particionamiento de la red, y replicación de datos entre diferentes grupos antes de que la red llegue a particionarse. • INSIGNIA: Esta es una plataforma cuyo objetivo de diseño es brindar QoS para asegurar un cierto ancho de banda destinado a la transmisión de flujos de datos, voz y video en tiempo real sobre MANETs [Lee, 2000]. Esta plataforma está compuesta de módulos que controlan el establecimiento, restauración, adaptación y destrucción de vínculos entre pares de nodos fuente-destino, y el establecimiento de protocolos de ruteo dinámicos que contemplan la topología cambiante de la red. A diferencia de iMAQ, la funcionalidad provista por esta plataforma está muy acotada a tipos de datos multimediales. • YCab: Es una plataforma orientada al intercambio de mensajes en escenarios distribuidos que ejecutan sobre MANETs [Buszko, 2001; Procopio, 2002]. Esta plataforma podría apoyar el desarrollo de aplicaciones de groupware móviles, a través de servicios que provee con una API. La implementación actual de YCab soporta comunicación sincrónica y asincrónica sobre redes IEEE 802.11x, incluyendo también multicast. La arquitectura de la plataforma está compuesta de un módulo para ruteo de mensajes, módulos para administración de comunicaciones, y un componente cliente que es responsable de la administración de los servicios y del mantenimiento de ciertas propiedades de estado (nombre, ranking, cola de mensajes, etc.). Además, YCab provee soporte para control descentralizado a través del uso de algoritmos de administración de sesión distribuida y elección de un coordinador. • Otros middleware: Existen varios otros proyectos como LaColla (Universitat Politécnica de Catalunya) [Marquès, 2005] y el Nokia Framework [Hirsch, 2006]. 12 1.4.2. Compartir Recursos entre Pares Entre las infraestructuras más importantes para apoyar el proceso de compartir recursos (datos, servicios, capacidad de procesamiento) en redes peer-to-peer, están las siguientes: • XMiddle: Proyecto de la University College London, un middleware de distribución de datos para la computación móvil. Funciona mediante el flujo de datos XML y permite realizar peticiones cuando los usuarios se encuentran desconectados [Mascolo, 2002]. Este middleware permite a los hosts móviles compartir datos cuando están conectados, replicar datos y ejecutar operaciones sobre ellos cuando están desconectados, o sincronizar datos cuando los hosts se reconectan. A diferencia de los sistemas basados en tuplas, cuya estructura de almacenamiento de datos es plana, XMiddle permite a cada dispositivo almacenar sus datos en una estructura de árbol. Esta estructura de árbol es implementada utilizando XML y tecnologías relacionadas. • T-Spaces: Desarrollado por IBM, T-Spaces es un conjunto de buffers para la comunicación de redes llamados espacios de tuplas (Tuplas-SPACES) y un conjunto de APIs y clases que las implementan para acceder a estos buffers. T-Spaces funciona en distintos tipos de dispositivos móviles siempre y cuando éstos tengan incorporado Java en sus sistemas [Wyckoff, 1998]. También existen otros proyectos similares como LIME [Handorean, 2003], Grace [Bosneag, 2005] y FT-Linda (University of Arizona) [Nemlekar, 2001]. • Jini: Jini es un middleware distribuido basado en la idea de registrar grupos de usuarios y recursos requeridos por dichos usuarios [Arnold, 1999]. El principal objetivo es convertir a la red en un medio flexible, de administración sencilla de recursos (dispositivos de hardware y programas de software) y de servicios, que pueden ser encontrados, agregados o eliminados por diferentes clientes. El más importante concepto en la arquitectura de Jini es el servicio. Un servicio es una entidad que puede ser usada por una persona, programa u otros servicios. Los servicios pueden ser encontrados usando un servicio de búsqueda provisto por un servidor central. Claramente esto limita la aplicabilidad de este middleware al escenario móvil especificado. • JavaSpaces: Es una especificación de servicios, desarrollada por Sun, enmarcada dentro de la tecnología Jini. Provee un mecanismo de intercambio y coordinación distribuida de objetos, la cual puede o no ser persistente. JavaSpaces es usado para alcanzar escalabilidad a través de procesamiento paralelo y provee almacenamiento confiable de objetos a la vez que reduce la complejidad de los sistemas distribuidos tradicionales. JavaSpaces es una implementación de la idea de los espacios de tuplas. • DACIA: Esta es una plataforma que permite crear aplicaciones colaborativas para dispositivos móviles [Litiu, 2004]. Cada dispositivo móvil tiene un motor (llamado PROC), el cual permite construir aplicaciones distribuidas basadas en componentes. El motor administra la escritura y re-localización de componentes, configuración de aplicación y administración de conexiones hacia otros dispositivos. Para su ejecución, DACIA se basa en un servidor central que guarda el estado de las aplicaciones que se están ejecutando en el dispositivo móvil. Si el dispositivo móvil se desconecta de un servidor A, y se re-conecta en un servidor B, el servidor A transmite el estado al servidor B, y luego el servidor B lo transmite al dispositivo móvil. Debido a que en el servidor se guarda el estado del dispositivo móvil, si dos usuarios móviles se desconectan y pretenden colaborar a través de sus aplicaciones, DACIA limita el tipo de interacción entre los usuarios hasta que se reconecten a 13 algún servidor. La necesidad de utilizar un servidor central hace que esta plataforma no sea aplicable al dominio definido. • Ad-hoc DSMS: Este es un sistema de memoria compartida distribuida, basado en chunks de memoria replicados, que mantiene una alta disponibilidad de la información distribuida sobre una MANET [Aldunate, 2006]. Este sistema particiona en dos secciones la memoria de los dispositivos que conforman la MANET. En una partición mantiene los datos propios de una aplicación distribuida, y en la otra mantiene datos replicados de otros colaboradores. Sólo dos réplicas de cada chunk de memoria se mantienen en el sistema. Los datos replicados son migrados dinámicamente entre máquinas, dependiendo de cuánto se acerquen éstas a los límites de la MANET. La posición de los colaboradores es determinada en función de la intensidad de la señal percibida por los dispositivos y un método de triangulación [Aldun04b, Pena02]. Aunque esta solución no está específicamente diseñada para ser usada en sistemas colaborativos, pues no considera roles ni distribución de datos en base a sesiones de trabajo, claramente podría usarse como base para generar las soluciones que se necesitan. El hecho de que Ad-hoc DSMS no utilice servidores, lo hace especialmente atractivo para evaluar la construcción de servicios de groupware por encima de él. Las plataformas y middlewares presentados brindan soluciones que apoyan aspectos muy puntuales del trabajo en escenarios distribuidos. Algunas de estas soluciones podrían aplicarse a escenarios de groupware. Sin embargo, el diseño de las soluciones no siempre es de dominio público. En general los productos que han sido desarrollados con fines comerciales o patrocinados por empresas, como YCab, TSpaces y Jini, no publican los diseños de las soluciones implementadas. De todos modos, la mayor parte de los aspectos típicos de diseño de las aplicaciones de groupware continúan aún sin una solución para aquellos escenarios de trabajo apoyados sobre una infraestructura móvil de comunicaciones. 14 2. Diseño e Implementación Este capítulo describe el diseño e implementación de los dos módulos mencionados anteriormente en este documento además de la incorporación de ambos al resto del middleware. Primero se describe la base técnica que se tomó en consideración para desarrollar el módulo Service Manager, junto a un testeo que validó la utilización de esta base. A continuación se describe la arquitectura del Service Manager y de que manera logra cumplir su finalidad, para cerrar con la descripción del módulo Mobile Units Profile Manager. 2.1. Proyectos Base para el Administrador de Servicios Web El administrador de servicios web fue desarrollado tomando como base la arquitectura del Smart Client Offline Application Block (SCOAB) del equipo Patterns & Practices de Microsoft junto a la del OpenNETCF Application Blocks 1.0 (OpenAB) del grupo OpenNETCF, ambos desarrollados para la plataforma .NET de Microsoft. SCOAB plantea un modelo de arquitectura que permite desarrollar aplicaciones del tipo smart client (cliente inteligente) con capacidades off-line. En términos simples, este modelo permite: a) detectar la presencia o ausencia de conectividad de red; b) almacenar datos de requerimientos para que la aplicación pueda seguir funcionando aunque no tenga conexiones disponibles; y c) sincronizar el estado y los datos de la aplicación cliente cuando la conectividad se recupere. 2.1.1. Clientes Inteligentes Previo al surgimiento de los smart clients, las aplicaciones eran consideradas clientes “gruesos” (thick client) o “delgados” (thin client). El primer tipo se caracteriza por aglomerar todas las aplicaciones en el computador cliente y por poseer una interfaz de usuario capaz de desplegar gráficos complejos y animaciones. Por otro lado, el segundo tipo mantiene a las aplicaciones almacenadas en el servidor y se dedica básicamente a obtener y desplegar datos. Un problema importante para los clientes “delgados” es que la información es transmitida al servidor mediante repetidas actualizaciones cíclicas, mermando su desempeño. Un problema a considerar de los clientes “gruesos” es que su distribución es compleja y provoca conflictos de portabilidad. El cliente “inteligente” surge como solución a estos problemas tomando las mejores características de los dos tipos de clientes anteriormente mencionados. Un cliente inteligente provee la misma interfaz rica que los thick clients pero con la simplicidad en el manejo de los cambios de los thin clients. Además un smart client puede proveer estas características mientras minimiza los recursos utilizados. 2.1.2. Smart Client Offline Application Block (SCOAB) Para lograr que un smart client opere correctamente, mientras se encuentra desconectado de la red, se pueden aplicar dos enfoques al desarrollo: un enfoque centrado en los datos, o un enfoque orientado a los servicios. 15 El enfoque centrado en los datos determina el empleo, por parte del cliente, de una base de datos local y un mecanismo de replicación para manejar los cambios que produce mientras la aplicación se encuentra en estado de desconexión. Con el enfoque orientado a los servicios, el cliente interactúa con un conjunto de servicios web a través de peticiones las cuales pueden ser retenidas durante los estados de desconexión. Estos enfoques se ven representados en la Figura 3. Figura 3. Enfoques para manejo de desconexiones Si bien el enfoque orientado a servicios demanda mayor trabajo en diseño y desarrollo que el enfoque centrado en datos, el SCOAB ha sido construido basado en el enfoque orientado a servicios debido a que la lógica del comportamiento de la aplicación durante su estado de desconexión se encapsula en el cliente, lo que da versatilidad y flexibilidad al desarrollo. La infraestructura necesaria para soportar funcionalidades offline que permitan almacenar los detalles de las peticiones de servicios para que sean ejecutadas cuando el cliente se reconecte a la red, consta de cuatro elementos principales, los cuales se ven representados en la Figura 4: • Agente de Servicios (Service Agent): Provee el acceso a los servicios web. Maneja toda la interacción con el servicio y encapsula los datos necesarios para que el cliente realice las peticiones de servicios. • Petición de Servicio (Service Request): Toda la información necesaria de una petición se encapsula en un objeto, el cual se almacena en una cola de peticiones hasta que el Ejecutor está preparado para procesarla. 16 • Cola de Peticiones (Service Request Queue): Cola que provee de almacenamiento para las Peticiones de Servicio. • Ejecutor (Executor): Es el responsable de procesar las Peticiones de Servicio almacenadas en la Cola de Peticiones y ejecutarlas cuando el cliente vuelva a conectarse a la red. Cada vez que una petición es completada, el ejecutor avisa al Agente para que éste pueda informar al cliente. Figura 4. Relación entre elementos de una infraestructura offline El SCOAB posee una serie de elementos que soportan la infraestructura previamente señalada. Estos elementos deben permitir detectar la presencia o ausencia de conectividad de red, para que con ello las aplicaciones modifiquen su comportamiento de estado conectado a estado desconectado y viceversa, proveer un sistema de almacenamiento de datos para permitir el funcionamiento de las aplicaciones durante los estados de desconexión, y posibilitar la sincronización del estado y/o los datos del cliente con el servidor cuando se vuelva al estado online. En la Figura 5 se puede apreciar sin incurrir en muchos detalles la arquitectura del SCOAB y su papel dentro de las aplicaciones tipo Smart Client. 17 Figura 5. Arquitectura del SCOAB Esta arquitectura presenta los siguientes subsistemas: • Connection State Management: Detecta si una aplicación se encuentra conectada o desconectada. • Service Agent Management: Interactúa con los subsistemas Reference Data Management, Message Data Management y con el servidor, coordinando tanto el envío de requisitos de servicios, como el aviso de completitud de tales peticiones. • Reference Data Management: Trabaja junto a los subsistemas Service Agent Management y Message Data Management para descargar información de referencia almacenada en un computador local, generalmente para completar un workflow. Almacena un mensaje en la cola para descargar la información de referencia. El Ejecutor luego toma el mensaje de requisito de servicio para conectarse con el servicio para descargar esta información. • Message Data Management: Son los datos creados durante un proceso del workflow. Cuando la aplicación está offline, la información es almacenada localmente en una cola. Cuando se vuelve a conectar, el Ejecutor toma un mensaje de la cola y crea una Petición de Servicio para sincronizar los datos con los del servidor. 2.1.3. OpenNETCF Application Blocks 1.0 (OpenAB) Si bien el SCOAB parece reunir todas las condiciones necesarias para ser la base del Administrador de Servicios del middleware, un ligero detalle no fue considerado en su concepción: un gran nicho de explotación de los smart clients son los contextos móviles, donde incluso un computador portátil es considerado demasiado grande. Para estos contextos los equipos ideales son los PocketPC, los cuales funcionan bajo una plataforma reducida del .NET Framework: el Compact Framework. El SCOAB está desarrollado fuera de los límites de este framework compacto, por lo cual es necesario una solución más “a medida” de los PocketPC. 18 Para abarcar estos contextos se desarrolló el OpenNETCFApplicationBlocks 1.0 el cual provee una arquitectura equivalente a la de SCOAB pero que corre sobre el .NET Compact Framework. Su arquitectura incorpora los mismos subsistemas que el SCOAB y maneja de igual manera el proceso de realizar un requisito de servicio. 2.1.4. Evaluación de Rendimiento Tomando como base el proyecto SCOAB, se procedió a construir una batería de pruebas para ver si era conveniente aprovechar este proyecto, o era necesario construir desde cero un sistema que administrase el manejo de requisitos a servicios durante períodos de desconexión. Las pruebas consistieron en comparar los tiempos que toma a un servidor web proveer funcionalidades a un smart client por medio del SCOAB con lo que demora en hacerlo sin él. Las funcionalidades testeadas fueron las siguientes: • void Accion(): Función que realiza una operación matemática predefinida, sin recibir ningún parámetro y sin entregar resultados. • int ObtenerNumero(): Función que provee al cliente de un número entero generado al azar sin recibir parámetro alguno. • int Sumar(int, int): Función que entrega la suma de dos números enteros entregados al servicio como parámetros. • XmlDocument ObtenerXml(): Función que crea un documento xml en blanco y se lo entrega al usuario, sin recibir parámetros. Cada función fue invocada en 3 series de 10, 50, 100, 500 y 1000 repeticiones, para ver el impacto provocado por las distintas exigencias en el rendimiento del cliente. Estas funcionalidades fueron alojadas en un servidor con IIS 5.1 (Internet Information Services). Los resultados obtenidos en estas pruebas se pueden ver en la Tabla 1. Tiempo de Respuesta [s] Función void Accion() int ObtenerNumero() int Sumar(int, int) Repeticiones 10 50 100 500 1000 10 50 100 500 1000 10 50 100 500 1000 19 c/SCOAB 0,013 0,068 0,134 0,49 1,18 0,013 0,07 0,137 0,581 1,05 0,013 0,069 0,137 0,473 1,178 s/SCOAB 0,164 0,288 0,413 0,885 1,828 0,182 0,376 0,586 1,526 3,269 0,199 0,464 0,739 2,329 4,62 Diferencia 0,151 0,22 0,279 0,395 0,648 0,169 0,306 0,449 0,945 2,219 0,186 0,395 0,602 1,856 3,442 XmlDocument ObtenerXml() 10 50 100 500 1000 0,022 0,112 0,163 0,995 1,619 0,226 0,596 0,902 3,316 6,704 0,204 0,484 0,739 2,321 5,085 Tabla 1. Tiempo de respuesta [s] de un servicio web con y sin SCOAB De la Tabla 1 se deduce que a medida que aumenta la complejidad de las instrucciones solicitadas, el tiempo de respuesta es mayor, así como sólo una demanda considerable (1000 o más repeticiones) rompe la linealidad de los tiempos obtenidos. Además se aprecia que la diferencia de tiempos entre utilizar el SCOAB y no utilizarlo no es limitante salvo en casos muy puntuales (como sería sobrepasar las 1000 repeticiones del test de sumas o de xml), por lo tanto la merma en el rendimiento no justificaría el desarrollo de una nueva infraestructura para soportar el funcionamiento offline del middleware. Si bien no se realizaron prueba de solicitudes simultáneas, debido a la naturaleza del test, la infraestructura del SCOAB está perfectamente capacitada para recibir solicitudes al mismo tiempo de diferentes usuarios. 2.2. Administrador de Servicios (Service Manager) El Administrador de Servicios fue desarrollado basado tanto en SCOAB (para aplicaciones basadas en .NET Framework 2.0) como en OpenAB (para aplicaciones construidas sobre .NET Compact Framework), cuyas estructuras son casi idénticas (el segundo fue desarrollado en semejanza al primero), por lo cual a continuación se explicará la estructura y funcionamiento del Service Manager sin hacer distinciones de plataforma. 2.2.1. Estructura Principal Como se explicó más atrás, para proveer de funcionalidades offline a una aplicación se debe de proveer una infraestructura particular a la aplicación que corra sobre este middleware. Esta infraestructura contiene componentes modificables por el creador de las aplicaciones sobre el middleware y componentes que no deben ser modificados. Los elementos no modificables de esta infraestructura son los siguientes: 1. Payload: Es el objeto que encapsula la petición de acceso a un servicio web. La Figura 6 muestra su estructura: 20 Figura 6. Estructura de un Payload Las propiedades de un Payload son las siguientes: • FailureReason: Es la propiedad que maneja la excepción asociada a cualquier falla o anomalía que pudiese suceder durante la invocación de la petición. • MethodToExecute: Es la información de contexto que corresponde a la invocación del servicio mediante el OnlineProxy. Incorpora el método a ejecutar del proxy así como también la información necesaria para que éste sea llamado a través de reflexión. • PayloadGuid: Es el identificador único del Payload. • RequestData: Es la información adicional que sirve para invocar al servicio web. Puede comprender parámetros de invocación u objetos que puedan ser necesarios para el proxy. • ResultCallbackTarget: Es la información de contexto que indica el método que será llamado una vez que el servicio web entregue respuesta. • Results: Aquí se almacena la información que es respondida por el servicio web una vez que la petición ha sido satisfecha. • ServiceAgentGuid: Es el identificador único del ServiceAgent que ha invocado al servicio. • Success: Es una variable booleana que indica si la petición se ha ejecutado con éxito o no. 21 2. QueueManager: Esta clase maneja la cola de peticiones de servicios (Payload) implementando las interfaces IQueueMessageProducer y IPayloadConsumer que le permiten, tanto encolar peticiones, como desencolarlas. La Figura 7 muestra la estructura de esta clase: Figura 7. Estructura del QueueManager Esta clase posee un único campo queueStorage que corresponde a un proveedor de almacenamiento que debe implementar la interfaz IQueueStorageProvider. Más adelante en el documento se explicará el proceso mediante el cual se escogió dicho proveedor. Además posee una única propiedad Size que entrega el tamaño actual de la cola. Por otro lado posee los siguientes métodos: • Dequeue: Método para obtener un objeto QueueMessage (recipiente de un Payload) de la cola. Se realiza un llamado al método Dequeue del proveedor de almacenamiento correspondiente. • Enqueue: Encola una petición en la cola, creando un QueueMessage a partir del Payload provisto como parámetro. También debe ser implementado por el proveedor. • Flush: Llamado al método de vaciado de la cola del proveedor de almacenamiento. • Load: Método que posibilita la carga de peticiones que han sido guardadas previamente en un documento xml, también implementado en el proveedor. • QueueManager: Constructor de un objeto QueueManager, tomando como parámetro un proveedor de almacenamiento. • Save: Llamada al método Save del proveedor, el cual realiza el encolamiento de peticiones almacenadas en un documento xml. 3. Executor: Es el objeto encargado de revisar la cola de peticiones, desencolando y procesando las peticiones mediante la creación de objetos OnlineProxy que a su vez invocan las funciones solicitadas en las peticiones. 4. OfflineBlockBuilder: Es el eje central de la infraestructura. Se encarga de arrancar el controlador de la detección de conexión (ConnectionManagerBuilder), el controlador de 22 encolamiento (QueueManagerBuilder) y el de ejecución (ExecutorBuilder), entre otros. Está construida en base al patrón Singleton debido a que es de suma importancia que no se pueda crear más de una instancia de esta clase, para no replicar controladores. En la Figura 8 se puede ver la estructura de esta clase y sus componentes. Figura 8. Estructura del OfflineBlockBuilder Esta clase incorpora entre sus campos los objetos que construyen (builders) los controladores antes mencionados (además de otros 3 controladores), propiedades para cada uno de ellos, y una propiedad especial para llamar a la instancia de esta clase. Entre sus métodos destacan su constructor privado y los métodos para poner en funcionamiento la infraestructura (Start) y para detenerla (Stop). Por otro lado, los componentes modificables de la infraestructura y que permiten desarrollar distintos tipos de aplicaciones sobre el middleware, son los siguientes: 1. ServiceAgent de la aplicación: Es una clase que corresponde al punto de acceso a los servicios web a los que puede acceder la aplicación. En ella se crean los objetos con las peticiones de servicio (Payload) que incluyen la información de contexto, tanto del servicio al que consultan, como de la función que llaman cuando el servicio entrega su respuesta. Los Payload son almacenados en una cola que luego el Executor se encarga de revisar. Esta clase debe ser modificada de acuerdo a los servicios que se desee acceder y los métodos de respuesta que se desea implementar. Un ejemplo de ServiceAgent se aprecia en la Figura 9: 23 Figura 9. Estructura de un ServiceAgent genérico Como se ve en el ejemplo, GenericServiceAgent hereda de la clase ServiceAgent e incorpora una instancia del OfflineBlockBuilder. También incorpora un método para invocar cada funcionalidad deseada del servicio web (en el ejemplo GenericAction), un método de callback para cada una de las invocaciones anteriores (en el ejemplo GenericActionCallback) y un evento por cada acción invocada (en este caso sólo una, el GenericActionEvent). Además se incluye un método de callback para cuando ocurre alguna excepción (ReportError) y un evento que lo llama (ReportErrorEvent). 2. OnlineProxy: Es el medio de comunicación directa con los servicios web. Esta clase implementa métodos que a su vez invocan las funciones de los servicios consultados. El Executor crea mediante reflexión un objeto OnlineProxy cada vez que desencola una petición, la cual invoca el servicio indicado en la información de contexto encapsulada en el Payload. Esta clase debe ser modificada indicándole los servicios a consultar, los parámetros a enviar (incorporados en el Payload) y los resultados que debe devolver a la función de callback indicada en el Payload. 3. Eventos: Por cada funcionalidad invocada, debe existir un delegado y una clase manejadora de eventos (que derive de la clase System.EventArgs) que maneje la información recibida luego de la invocación de un servicio y que permita a la función de callback saber cuando se ha completado una petición. En la Figura 10 se distingue un ejemplo de los delegados y eventos a implementar: Figura 10. Estructura de un delegado y un evento de ejemplo 24 A continuación se detalla, a través de una serie de pasos, la manera que tiene de operar el Service Manager con las peticiones de servicios. Estos pasos se ven representados por la Figura 11: 1. La aplicación realiza una petición a un servicio web a través de su implementación del ServiceAgent, la cual crea un objeto Payload, que incorpora la información de contexto necesaria para la petición (OnlineProxyContext) y para la respuesta (ServiceAgentContext). 2. Luego el ServiceAgent encola la petición a través del QueueManager. 3. El Executor, que está constantemente esperando por peticiones, desencola el QueueMessage que contiene la petición. 4. El Executor recupera la información de contexto desde el Payload y crea una instancia de OnlineProxy a través de reflexión, con la cual ejecuta el llamado al servicio web. 5. Después de esta ejecución, los resultados son almacenados en el Payload, el cual es retornado al ServiceAgentManager, el controlador de agentes de servicio del OfflineBlockBuilder. 6. El ServiceAgentManager recupera el identificador del ServiceAgent que creó la petición desde la información de contexto incluída en el Payload, para enviarle los resultados de la petición. 7. El ServiceAgentManager envía la respuesta al ServiceAgent apropiado, donde se invoca a la función indicada en el ServiceAgentContext. Figura 11. Flujo de una petición de servicio 25 2.2.2. Elección de Proveedor de Almacenamiento Como se mencionó en el punto anterior, el manejador de colas (QueueManager) ofrece distintos proveedores de almacenamiento para la cola de solicitudes. Un proveedor de almacenamiento es una clase tal que extiende la clase abstracta QueueStorageProvider, particularmente implementando los métodos abstractos que ésta obtiene de la interfaz IQueueStorageProvider. Estos métodos (Dequeue, Enqueue, Flush, Load y Save) ya fueron explicados en la sección anterior. La estructura del QueueStorageProvider, así como la de las interfaces que implementa, se observa en la Figura 12. Figura 12. Estructura del QueueStorageProvider y las interfaces que implementa Si bien el Service Manager posee por defecto tres proveedores comunes a ambas plataformas (.NET Framework y .NET Compact Framework), fue necesario evaluar su rendimiento, para escoger el óptimo cuando se trata de aplicaciones que corren sobre unidades con hardware reducido (PocketPCs, UMPCs, etc.). Los proveedores evaluados fueron los siguientes: • InMemoryQueueStorageProvider: Este proveedor almacena las peticiones en memoria, en un objeto System.Collections.Queue de funcionamiento FIFO (First In, First Out), cuya gran desventaja es no poder almacenar persistentemente las peticiones. 26 • MSDEQueueStorageProvider: Este proveedor utiliza el servidor de SQL MSDE para almacenar las peticiones. Si bien ofrece persistencia de datos, MSDE es un recurso compartido, por lo que no se recomienda su uso cuando más de un usuario pretenden utilizar una aplicación en la misma máquina. • MSMQQueueStorageProvider: Este proveedor almacena las peticiones en el sistema de colas y mensajes de Windows, Message Queue Server (MSMQ). La prueba que se realizó para evaluar el rendimiento de estos proveedores fue una serie de tests de stress de invocaciones de funciones de un servicio web. El servicio utilizado es el mismo que se utilizó en la prueba de factibilidad del uso de SCOAB. Los tests consistieron en tres series de 10, 50, 100, 500 y 1000 repeticiones de invocaciones a cada funcionalidad del servicio bajo las siguientes condiciones: • Con el servicio corriendo sobre IIS 5.1 en un PC, o sin CodeBehind. o con CodeBehind. • Con el servicio corriendo sobre el MicroWebServer [Carrasco, 2007], o en un PC. o en una PocketPC Dell Axim x50. o en una PocketPC HP iPAQ hx4700. Una breve comparación técnica de los dispositivos utilizados como servidores en estas pruebas puede apreciarse en la Tabla 2: Dispositivo PC Pocket PC Dell Pocket PC HP Procesador 1.67 GHz 624 MHz 624 MHz Memoria 768 MB RAM 64 MB RAM / 128 MB ROM 64 MB RAM / 128 MB ROM Tabla 2. Comparación técnica de servidores De las dos primeras pruebas saltó a la vista que realizar el manejo de peticiones a través de encolamiento en memoria es considerablemente más rápido que a través de MSDE y MSMQ (que a la postre resultó ser el más costoso). Comparando los tiempos con y sin uso de CodeBehind, lo que corresponde a alojar el servicio web compilado en una librería en vez de alojar el código fuente, se obtuvieron resultados similares, marcando una ligera ventaja comparativa el uso del CodeBehind. Los resultados de estas pruebas están expuestos en la Tabla 3. Rep 10 50 100 500 1000 Servicio Web sin CodeBehind void Accion() int ObtenerNumero() InMemory MSMQ MSDE Rep InMemory MSMQ MSDE 0,254 0,333 0,372 10 0,326 0,425 0,445 0,456 5,334 0,618 50 0,785 7,145 1,141 0,811 8,317 1,751 100 1,483 14,454 3,328 3,371 210,818 17,077 500 6,398 361,213 35,5 6,356 839,823 56,448 1000 12,438 1449,538 109,312 27 Rep 10 50 100 500 1000 int Sumar(int, int) InMemory MSMQ 0,388 0,526 1,1 8,358 2,148 18,453 9,461 446,177 18,626 1810,257 XmlDocument ObtenerXml() MSDE Rep InMemory MSMQ MSDE 0,508 10 0,472 0,653 0,6 1,593 50 1,56 9,137 2,142 4,873 100 2,992 20,578 6,621 53,554 500 13,909 477,132 71,434 160,474 1000 26,999 1922,133 210,99 Rep: Repeticiones Rep 10 50 100 500 1000 Servicio Web con CodeBehind void Accion() int ObtenerNumero() InMemory MSMQ MSDE Rep InMemory MSMQ MSDE 0,372 0,226 0,316 10 0,427 0,32 0,529 0,412 2,281 1,513 50 0,675 3,925 2,767 0,724 8,121 3,571 100 1,221 14,092 6,486 2,773 220,554 19,735 500 5,308 371,058 37,899 5,414 841,547 53,309 1000 10,407 1451,614 105,617 Rep 10 50 100 500 1000 int Sumar(int, int) InMemory MSMQ 0,484 0,413 0,943 5,089 1,732 18,102 7,811 458,57 15,536 1807,012 XmlDocument ObtenerXml() MSDE Rep InMemory MSMQ MSDE 0,774 10 0,555 0,503 1,069 4,033 50 1,31 5,851 5,63 9,178 100 2,445 20,098 12,2 55,781 500 11,396 488,912 73,234 145,115 1000 22,772 1918,9 181,154 Rep: Repeticiones Tabla 3. Tiempo de respuesta [s] de un servicio corriendo sobre IIS Los resultados de las siguientes tres pruebas, los cuales son los más importantes ya que uno de los objetivos de esta memoria es integrar el uso del Service Manager con el MicroWebServer, indicaron que el MicroWebServer no necesariamente incorpora una merma al rendimiento ya que, como se aprecia en la Tabla 4, los tiempos obtenidos son estrechamente similares a los obtenidos con el servicio web alojado en IIS. Aquí también se manifiesta un manejo más expedito de las peticiones por parte del proveedor de almacenamiento en memoria, por sobre los rendimientos de MSDE y MSMQ. Cabe destacar que en estas tres pruebas el servicio hizo uso de CodeBehind debido a que es un requisito del MicroWebServer. Rep 10 50 100 500 1000 void Accion() InMemory MSMQ 0,162 0,314 0,444 2,167 0,719 7,611 2,471 209,552 4,972 814,851 Rep 10 50 100 int Sumar(int, int) InMemory MSMQ 0,258 0,543 0,927 4,832 1,685 16,726 MicroWebServer en PC int ObtenerNumero() MSDE Rep InMemory MSMQ MSDE 0,559 10 0,21 0,441 0,93 1,941 50 0,685 3,725 3,62 4,171 100 1,204 13,012 8,063 22,044 500 4,881 359,872 40,411 54,946 1000 9,864 1425,953 105,625 XmlDocument ObtenerXml() Rep InMemory MSMQ MSDE 10 0,331 0,636 1,699 50 1,285 5,597 7,457 100 2,418 19,015 15,376 MSDE 1,301 5,508 11,685 28 500 1000 7,385 14,911 447,046 1783,382 58,695 500 155,902 1000 Rep: Repeticiones 11,043 22,212 477,676 1892,448 77,53 203,077 Tabla 4. Tiempo de respuesta [s] de un servicio corriendo sobre el MicroWebServer en un PC El rendimiento de los proveedores baja cuando cambiamos la plataforma sobre la cual se ejecuta el MicroWebServer. Como se observa en la Tabla 5, cuando se cuenta con hardware reducido (en este caso PocketPCs) los tiempos de respuesta de los proveedores se incrementan considerablemente, por ejemplo en el caso del método Accion se produce un aumento en el tiempo de respuesta promedio superior a 20.000% cuando se prueba usando una PocketPC Dell X50 como servidor. A su vez, la comparativa entre los rendimientos obtenidos con el uso de las dos PocketPC nos muestra datos razonables para dos equipos de similares características, mostrando una diferencia promedio cercana al 16%, diferencia que puede deberse a la calidad y ensamblado de los materiales de uno y otro equipo. Varias de las series de estas pruebas no se realizaron debido a que los tiempos alcanzaron rangos excesivos, y las tendencias ya eran capaces de ser sometidas a análisis y comparaciones. Rep 10 50 100 500 1000 Rep 10 50 100 500 1000 MicroWebServer en PocketPC Dell X50 void Accion() int ObtenerNumero() InMemory MSMQ MSDE Rep InMemory MSMQ MSDE 18,16 22,373 26,815 10 46,051 45,07 51,008 51,358 122,219 108,625 50 96,657 243,806 222,376 160,241 391,108 331,625 100 346,841 858,192 733,408 965,276 NR NR 500 2000,33 NR NR 1937,251 NR NR 1000 4164,129 NR NR int Sumar(int, int) XmlDocument ObtenerXml() InMemory MSMQ MSDE Rep InMemory MSMQ MSDE 66,564 68,018 75,144 10 82,589 90,921 99,07 204,042 361,964 327,733 50 315,252 476,042 447,439 520,263 1093,133 1029,086 100 700,309 1585,219 1516,182 3094,921 NR NR 500 4257,501 NR NR 6487,127 NR NR 1000 NR NR NR Rep: Repeticiones; NR: No Realizado Rep 10 50 100 500 1000 MicroWebServer en PocketPC HP iPAQ hx4700 void Accion() int ObtenerNumero() InMemory MSMQ MSDE Rep InMemory MSMQ MSDE 9,487 9,206 12,458 10 17,357 24,094 26,413 80,418 469,396 398,656 50 186,996 575,763 483,379 214,836 1173,49 996,64 100 437,163 1353,031 1208,348 1056,618 NR NR 500 2168,638 NR NR 2115,839 NR NR 1000 4439,827 NR NR Rep 10 50 100 int Sumar(int, int) InMemory MSMQ MSDE 25,598 46,895 53,212 295,75 681,014 659,828 659,806 1661,742 1549,572 Rep 10 50 100 29 XmlDocument ObtenerXml() InMemory MSMQ MSDE 44,413 68,845 75,441 404,379 790,541 771,743 887,722 2042,687 1889,436 500 1000 3282,551 6911,997 NR NR 500 4440,852 NR NR 1000 NR Rep: Repeticiones; NR: No Realizado NR NR NR NR Tabla 5. Tiempo de respuesta [s] de un servicio corriendo sobre el MicroWebServer en PocketPCs Para finalizar las pruebas se realizó un test de stress para evaluar la responsabilidad del Service Manager en el bajo rendimiento de las PocketPCs como servidores. Si bien, tomando en cuenta los resultados en la Tabla 6, el Service Manager produce un alto impacto en los tiempos de respuesta, los tiempos obtenidos en esta prueba también son altos, lo que atribuye la responsabilidad, en su mayor parte, a las bajas prestaciones de los equipos móviles. Función Repeticiones 10 100 10 100 10 100 10 100 void Accion() int ObtenerNumero() int Sumar(int, int) XmlDocument ObtenerXml() Tiempo de Respuesta [s] 7,923 206,023 8,993 213,834 8,556 218,865 17,845 220,753 Tabla 6. Tiempo de respuesta [s] de un servicio corriendo sobre una PocketPC Dell sin Service Manager En resumidas cuentas, de las pruebas mencionadas se desprende que el proveedor que entrega el mejor rendimiento general es el InMemoryQueueStorageProvider, superando por amplio margen a sus dos competidores. Pero como se mencionó antes, este proveedor posee una gran desventaja, la cual es no poseer un mecanismo de persistencia de sus registros, por lo que se hizo necesario implementar funciones que posibilitan el grabado persistente de la cola y la recuperación de estas peticiones. 2.2.3. Mecanismos de Persistencia de la Cola Los mecanismos de persistencia construidos fueron los métodos DoSave y DoLoad, los cuales fueron implementados directamente en el proveedor escogido para utilizar en el Service Manager, además de incluidos en la firma de la clase abstracta QueueStorageProvider (clase de la cual heredan los proveedores de almacenamiento). Por otro lado, para que la aplicación pueda acceder a estas funciones, se incorporó en las interfaces IPayloadConsumer y IQueueStorageProvider (interfaces que son implementadas por QueueStorageProvider) las firmas de métodos Save y Load, las cuales dotan al controlador de ServiceAgents (ServiceAgentManager) del OfflineBlockBuilder de acceso a estas funcionalidades. La persistencia de la cola se realiza a través del siguiente procedimiento: se recorre la cola de peticiones, y cada petición es serializada (se obtiene el equivalente del objeto en bytes) y almacenada en un documento xml (queue.xml) bajo la etiqueta <message>. Para recuperar los mensajes del documento, se revisa el documento obteniendo cada una de las peticiones serializada y por medio de deserialización se recupera el objeto correspondiente a cada petición. Un ejemplo de este archivo de peticiones es el siguiente: 30 <messages> <message>0 1 0 0 255 255 255 255 ... 0 102 77 105 99</message> ... <message>0 1 0 0 255 255 255 255 ... 0 102 77 105 99</message> </messages> Estos métodos están construidos pensando en su utilización en casos de cierre de aplicaciones y no en períodos de desconexión, ya que la estructura del administrador de servicios heredada de SCOAB (y OpenAB) se encarga de estos contextos. 2.3. Administrador de Perfiles de Unidades Móviles (Mobile Units Profile Manager) La finalidad del administrador de perfiles de unidades móviles es proveer a las aplicaciones ejecutadas sobre el middleware de la información de contexto necesaria para permitir el trabajo en conjunto de distintas unidades móviles. Esta información es provista a través de perfiles de cada unidad, para lo cual fue necesario definir un formato adecuado para su intercambio entre los distintos actores involucrados en la ejecución de las aplicaciones soportadas por el middleware. Por otro lado, se desarrolló un sistema de roles genérico el cual permite a las diferentes aplicaciones basadas en la plataforma hacer distinción entre diversos tipos de usuario, con el fin de otorgar privilegios sobre archivos, acceso a opciones de software, etc. La clase ProfileManager se construyó siguiendo el patrón Singleton con el fin de no permitir crear más de una instancia a la vez de esta clase. Esta clase incluye entre sus campos las características del perfil administrado, cada una con su propia Property, además de la propiedad para obtener la única instancia de esta clase (Instance). También incorpora un constructor privado el cual posibilita la implementación acorde al patrón. La estructura de esta clase se aprecia en la Figura 13. Figura 13. Estructura del ProfileManager 31 2.3.1. Descripción del Perfil de una Unidad Cada unidad móvil poseerá un perfil que la identificará dentro de las MANETs entregando a las demás unidades datos como un identificador único, sus características técnicas y la plataforma sobre la cual se ejecuta. Además almacena un indicador de la última actualización del perfil. Un ejemplo de un perfil es el siguiente: <profile> <unit_id>b8ca85f0-2128-45d9-8036-4e3070e56106</unit_id> <unit_type>PC</unit_type> <unit_platform>WinCE</unit_platform> <unit_cpu>AthlonXP 2000+</unit_cpu> <unit_mem>768 MB</unit_mem> <unit_norm>802.11g</unit_norm> <user_name>Claudio</user_name> <user_role>Administrador</user_role> <shared_files> <file user=”Claudio”>C:\Música\cancion.mp3</file> <file user=”Andrés”>C:\Trabajo\documento.doc</file> </shared_files> <services_available> <service>Servicio1</service> <service>Servicio4</service> </services_available> <last_update>10/28/2006 12:45:51</last_update> </profile> En el perfil anterior existen los siguientes atributos (los marcados con negrita en el ejemplo anterior están actualmente implementados en la clase ProfileManager): • unit_id: Identificador único de la unidad, de formato similar a “b8ca85f0-2128-45d9-80364e3070e56106”. • unit_type: Tipo de dispositivo (PDA, teléfono celular, computador personal). • unit_platform: Sistema operativo de la unidad (WinXP, Win2000, Mobile 2005, etc.). • unit_cpu: Procesador de la unidad. • unit_mem: Memoria RAM de la unidad. • unit_norm: Norma de conexión inalámbrica del dispositivo (802.11 b/g, otras). • user_name: Nombre del usuario que utiliza la unidad. • user_role: Rol del usuario que utiliza la unidad. • shared_files: Listado de archivos compartidos por el usuario. o file: Ruta del archivo compartido. • user: Usuario dueño del archivo. services_available: Listado de servicios ofrecidos por la unidad. o service: Nombre del servicio. 32 • last_update: Marca de tiempo (timestamp) de la última actualización del perfil. Se escogió utilizar el formato xml para la definición de los perfiles debido a que es una tecnología ampliamente conocida, con grandes ventajas en el campo de comunicación (al ser documentos de texto plano son fáciles de crear, transmitir y leer) y además es muy utilizada en el ámbito de los servicios Web. 2.3.2. Sistema de Roles Para manejar los privilegios con que cuentan los usuarios del middleware se planteó un sistema de roles flexibles y dependientes del contexto. Esto quiere decir que los permisos y/o jerarquías del sistema dependen de la aplicación que esté siendo ejecutada en la unidad. Estos permisos regularán el acceso del usuario, tanto a las funciones de una aplicación, como a la información y documentos compartidos de otros usuarios de las aplicaciones. Para esto se define un set de roles con nombres no jerárquicos (es decir, se evitan los nombres tipo alpha/beta/gamma o admin/usuario que definan explícitamente una jerarquía u orden) que pueden ser del estilo red/green/blue, los cuales son utilizados por las aplicaciones definiendo una serie de relaciones que pueden ser del estilo “puede ver archivos de” o “puede copiar archivos de”. Un ejemplo de esto se visualiza en la Figura 14. Figura 14. Ejemplo de relaciones jerárquicas entre roles de usuario La Figura 14 muestra como en dos aplicaciones distintas del middleware (A y B) la relación “puede ver archivos de” no se comporta de igual manera entre los tres tipos de usuarios existentes: en la aplicación A, el tipo de usuario red es una especie de “superusuario” ya que tiene acceso a los 33 archivos de los tres tipos de usuario, el tipo de usuario green es intermedio y blue tiene los menores privilegios pudiendo sólo ver los archivos de los usuarios de su tipo. Pero esto cambia en la aplicación B, donde cada tipo de usuario puede ver los archivos de los usuarios de su mismo tipo y de los usuarios de tipo green. Este sistema puede también aprovechar las bondades de xml y realizar sus definiciones mediante documentos xml donde se definan los distintos roles o tipos de usuario y la relaciones existentes entre ellos. Con un sistema de estas características se gana flexibilidad en el desarrollo de aplicaciones para el middleware sin mermar la compatibilidad que pueda existir entre éstas. 34 3. Descripción de la Aplicación Desarrollada Si bien se había probado la correcta interacción del Service Manager con el MicroWebServer, los servicios testeados proveían funcionalidades de baja complejidad (por ejemplo, entregar números aleatorios, realizar aplicaciones aritméticas, operaciones con cadenas de texto, creación de objetos, etc.) por lo que había que probar esta colaboración con servicios que involucrasen procedimientos más complejos. 3.1. File Sharing Test Para probar esta colaboración se escogió utilizar el servicio FileSharingMobileService (incluido dentro del desarrollo del MicroWebServer) como servicio de prueba, ya que éste provee de funcionalidades de intercambio de archivos, las que revisten el nivel deseado de complejidad a probar. Este servicio se compone de la clase FileSharing (cuya estructura se aprecia en la Figura 15), la cual posee un campo col que se encarga de almacenar los tipos de archivo a filtrar (se consideran “descargables”) y los siguientes métodos: • FileSharing: Es el constructor de esta clase y se encarga de inicializar la variable col con los tipos de archivos descargables predefinidos, entre los que se encuentran archivos de imagen (gif, jpeg y jpg), archivos de audio y video (mp3 y mpeg) y archivos comprimidos (zip), entre otros. • GetFileNames: Esta función revisa un directorio dentro del servidor, indicado por el parámetro path, y entrega una lista con los nombres y tamaños de todos sus archivos descargables. Para almacenar esta información se utiliza la clase FileShareInfo, la cual posee solo dos variables de instancia que almacenan el nombre y el tamaño de un archivo. • GetFiles: Este método envía los archivos indicados en el parámetro files, utilizando para ello el protocolo de archivos adjuntos Dime [Carrasco, 2007]. Figura 15. Estructura del servicio FileSharingMobileService Para la prueba se desarrolló una aplicación, File Sharing Test, que se comunica con este servicio a través del MicroWebServer, y utilizando además el Service Manager para la regulación del flujo de las peticiones de servicio. Esta aplicación implementa todos los elementos necesarios para el manejo de peticiones en estados de desconexión mencionados en el punto 2.2.1, como por ejemplo un 35 agente de servicio adaptado (FileSharingTestSA), un proxy apropiado (OnlineProxy) y los manejadores de eventos requeridos. La interfaz gráfica de usuario (GUI) de la aplicación (mostrada en la Figura 16) incluye campos de texto para indicar el servidor al cual conectarse, la carpeta remota donde buscar archivos y la carpeta local donde almacenar las descargas, un panel donde se muestran los archivos descargables y de donde se pueden seleccionar para su posterior descarga, y botones para solicitar la lista de archivos desde el servidor, iniciar la descarga de archivos y cambiar el estado de conexión. Figura 16. Interfaz gráfica (GUI) de File Sharing Test El proceso mediante el cual se descargan los archivos seleccionados, es algo complejo debido a que involucra la utilización el protocolo de archivos adjuntos Dime (ya que la función de descarga de archivos del servicio web posee el atributo “[Dime]”). Cuando el servicio web recibe la petición de descarga, crea un objeto DimeAttribute el cual posee una lista donde se almacenan las peticiones de descarga en el formato DimeAttachment que incorpora la dirección y el tipo del archivo a descargar. Cuando el proxy recibe la respuesta del servicio web, revisa la lista y por cada elemento en ella crea un archivo a partir de un flujo de bytes obtenido a través de los DimeAttachments. Otro detalle importante a considerar de esta aplicación, es la incorporación de la posibilidad de desconectarse de la red. Cuando se presiona el botón Online, el OfflineBlockBuilder de la aplicación llama a su controlador del estado de conexión (ConnectionManager) y hace que éste pase al estado desconectado, con lo cual las peticiones se empiezan a acumular en el QueueManager y no pasan al Executor, hasta que el ConnectionManager no pase a estado conectado, lo cual sucede cuando se vuelve a presionar el botón. Cuando se recupera la conexión el Executor accede a las peticiones y éstas se procesan, obteniendo los resultados que estaban pospuestos. Lo mismo ocurre cuando existen peticiones sin procesar y la aplicación es cerrada, las peticiones se guardan de la manera mencionada en el punto 2.2.3, con la diferencia que este caso las peticiones se guardan en un documento xml y no en memoria. 36 3.2. Integración al Middleware Además del desarrollo de los módulos de Administración de Servicios (Service Manager) y de Administración de Perfiles de Unidades Móviles (Mobile Units Profile Manager), uno de los objetivos de este trabajo de título es la integración estos componentes al resto del middleware. Una muestra de esta integración es el desarrollo antes descrito de File Sharing Test, donde se aprecia claramente la colaboración efectiva entre el MicroWebServer y el Service Manager. El Service Manager aprovecha de buena manera las características del MicroWebServer permitiendo una correcta comunicación, enviando peticiones, encolándolas sin problemas y recibiendo respuestas (y descargas de archivos) dentro de tiempos razonables (esto será explicado más adelante en el capítulo de Resultados). Por otro lado, el Profile Manager también se integra al middleware de manera efectiva. Lo hace por medio del Service Manager, cuando una aplicación que corre sobre el middleware inicializa su Service Agent diseñado a medida, éste inicializa a través de su clase madre (Service Agent) la clase ProfileManager la cual carga toda la información correspondiente al dispositivo utilizado. Finalmente, se diseñó una interfaz gráfica de usuario para mostrar las opciones de interacción entre los distintos componentes del middleware, de la cual se aprecian algunas pantallas en la Figura 17. En la pantalla (a) se ve que en la grilla superior se tiene la lista de los traspasos activos, ya sean estos descargas o envíos, con sus principales características. Haciendo un clic largo (mecanismo de interacción propio de las PocketPC) se obtiene un menú contextual de la descarga desde donde se puede escoger cancelar o detener la descarga. En el caso de la detención manual de una descarga, ésta pasa a estado de inactividad y deja la lista superior para pasar a la grilla inferior donde se tiene la lista de los traspasos detenidos que incluye también a los que se encuentran en pausa, ya sea por desconexión o por problemas de espacio en el dispositivo. Aquí se encuentra un menú contextual de donde se puede cambiar el estado de una descarga o cancelarla. También es importante destacar que ambas listas involucran descargas realizadas dentro de una sesión dada, la cual puede cambiarse haciendo uso del combobox dispuesto en la parte baja de la pantalla. En la pantalla (b) se muestra una interfaz gráfica de búsqueda de recursos compartidos dentro de las distintas sesiones a las que pertenece el usuario. Para ello hay habilitado un filtro de búsqueda por usuario o nombre de recurso (en forma de un combobox), y los resultados se despliegan en una grilla habilitada bajo el filtro. Lo que buscan mostrar estas interfaces gráficas es la interacción entre los componentes del middleware antes mencionados y la administración de sesiones de usuarios, realizada por el módulo detector de presencia de dispositivos móviles en la red (Mobile Units Near Me). Con estos cuatro componentes integrados se pueden implementar diversos tipos de aplicaciones móviles, adaptándose a los diferentes escenarios de colaboración existentes hoy en día. 37 Figura 17. Interfaces de muestra de integración del middleware 38 4. Resultados Obtenidos Durante el desarrollo de este trabajo de título, se llevaron a acabo varias pruebas sobre distintos elementos de la implementación. La mayoría de éstas tuvieron como finalidad ayudar a la toma de decisiones dentro del desarrollo, por ejemplo, la primera prueba descrita en este documento tuvo por objetivo confirmar la viabilidad del uso de SCOAB y OpenAB como base del desarrollo del Service Manager, mientras que la segunda buscaba escoger el mejor proveedor de almacenamiento de peticiones. Al final del desarrollo se realizó un test final de stress para obtener los rendimientos del Service Manager cuando se realiza traspaso de archivos. Esta prueba se construyó a partir de la infraestructura que sostiene la aplicación File Sharing Test (explicada en el capítulo anterior) y consiste en realizar una serie de peticiones de descarga de archivos de distintos tamaños. Otro parámetro considerado en las pruebas fueron los dispositivos que están involucrados en éstas. Se obtuvo el rendimiento bajo cinco situaciones diferentes, en las que el rol de cliente y servidor fue intercambiado entre un computador de escritorio, un notebook y un computador de bolsillo. Las descripciones técnicas de estos dispositivos pueden encontrarse en la Tabla 7, y los resultados de estas pruebas en la Tabla 8. Dispositivo Procesador Memoria PC Escritorio (PC1) Notebook (PC2) Pocket PC HP 1.67 GHz 2.0 GHz 624 MHz 768 MB RAM 1.25 GB RAM 64 MB RAM / 128 MB ROM Tabla 7. Comparación Técnica de Dispositivos Rep 1 5 10 20 50 Rep 1 5 10 20 50 Rep 1 5 Servidor: PC1 Cliente: PocketPC Tamaño del Archivo [KB] 100 200 500 1000 2000 6 7 9 16 22 22 24 34 57 123 29 33 64 105 266 70 74 136 282 558 150 163 391 727 1437 3000 32 160 393 849 1970 Servidor: PocketPC Cliente: PocketPC Tamaño del Archivo [KB] 100 200 500 1000 2000 3 3 5 8 15 16 13 33 62 128 20 26 69 122 185 41 73 148 273 506 166 174 370 731 1305 3000 24 157 372 744 1891 Servidor: PC1 Cliente: PC1 Tamaño del Archivo [KB] 100 200 500 1000 2000 0,64 0,98 1,03 1,08 1,55 2,20 2,44 2,56 4,56 6,47 3000 1,97 8,56 39 10 20 50 Rep 1 5 10 20 50 Rep 1 5 10 20 50 3,63 7,44 17,30 12,89 24,13 59,52 16,73 33,72 81,00 Servidor: PC1 Cliente: PC2 Tamaño del Archivo [KB] 200 500 1000 2000 0,69 1,33 1,61 2,39 2,81 3,34 6,84 10,11 4,47 6,58 12,39 20,67 8,78 13,97 24,64 41,17 25,20 30,06 59,50 101,28 3000 3,06 15,09 28,91 58,63 143,48 Servidor: PocketPC Cliente: PC1 Tamaño del Archivo [KB] 100 200 500 1000 2000 2,03 2,95 4,14 7,16 12,95 14,39 19,59 37,58 45,33 97,78 32,13 40,63 53,36 108,17 168,00 62,30 73,11 117,03 185,34 323,78 186,25 211,23 339,23 471,72 875,42 3000 22,95 123,58 233,28 494,05 1276,55 100 0,42 2,45 4,30 8,44 19,95 3,91 7,55 17,56 4,17 7,80 19,38 8,38 15,83 38,98 Tabla 8. Tiempo de respuesta [s] de traspasos sucesivos entre distintos tipos de servidores y clientes De los resultados anteriores se puede desprender las siguientes conclusiones: • Los tiempos de respuesta empeoran si el traspaso se hace externamente: Si el dispositivo que cumple el rol de servidor es distinto al que hace de cliente, las descargas toman en promedio más tiempo que si se hace el traspaso en un solo dispositivo (en el caso de PocketPC se demora en promedio un 25% más y en el caso de PC un 40%). El porcentaje de merma es menor en el caso de PocketPC porque en ambos casos sus tiempos son altos, pero en ningún caso los tiempos pueden ser considerados inmanejables. Esto es de importancia ya que las descargas en contextos reales se realizarán normalmente entre distintos dispositivos. • Los tiempos de respuesta empeoran cuando hay involucrada una PocketPC: Debido a sus limitaciones de hardware, el tiempo obtenido en las pruebas en que un computador de bolsillo juega alguno de los roles (o ambos), es considerablemente mayor que cuando no está presente (incremento de más del 1000% en el caso ‘PocketPC + PocketPC’ versus ‘PC1 + PC1’). En este caso los tiempos tampoco son tan altos, y en el caso de archivos de menor tamaño (<1000 KB) los tiempos son bastante abordables, y en la mayoría de los escenarios móviles en que se puede aplicar el traspaso de documentos, los tamaños de éstos no tendrían que superar necesariamente este umbral. • Los tiempos de respuesta más altos, son obtenidos cuando se exige una mayor cantidad de repeticiones, sin embargo no en todos los escenarios se hace necesaria una alta demanda de recursos (principalmente en entornos de intercambios de archivos peer-topeer). En escenarios de trabajo colaborativo, donde se requiere de sincronización e intercambio de información en momentos específicos de la jornada laboral, es completamente factible operar con los tiempos obtenidos. 40 5. Conclusiones y Trabajo a Futuro El campo de acción de las tecnologías móviles crece día a día y con él crece también la necesidad de respuestas tecnológicas más rápidas y que brinden mayor independencia a los trabajadores móviles. Los servicios web entregan la integración que necesitan estos sistemas para interactuar. El middleware, del cual se han desarrollado dos componentes de gran importancia en este trabajo de título, se convierte en un importante soporte para las aplicaciones basadas en servicios Web, ya que además de transformar a dispositivos de bajas prestaciones, como lo son las PocketPC, en verdaderos servidores web, permite manejar estos recursos en escenarios de escasa e inestable conectividad (por medio del módulo Service Manager), adecuando el comportamiento de las aplicaciones a las características del dispositivo que las ejecuta (por medio del módulo Profile Manager). Una característica destacable del trabajo realizado, es que el Service Manager se adapta sin mayores dificultades a las necesidades de la aplicación que se desea desarrollar, ya que posee componentes configurables que permiten crear diferentes opciones de conexión a servicios, por ejemplo si se requiere cumplir con algún estándar en particular (como en el caso de File Sharing Service donde se utilizó el protocolo Dime) basta crear componentes intermedios que sirvan de bypass entre los elementos del módulo y los requerimientos de la aplicación. El mantener un perfil de las unidades donde se usan aplicaciones creadas con el middleware, posibilita la optimización del uso de recursos de las aplicaciones: éstas pueden tener comportamientos variables según las prestaciones de la máquina que las esté ejecutando, o también pueden ofrecer distintas funcionalidades según el dispositivo que se utilice. También posibilita el uso de la misma unidad por parte de distintos usuarios sin tener que declarar los mismos recursos compartidos o tener acceso a las mismas opciones, porque existe un diseño de un sistema de roles adecuado a estos contextos. La integración de estos sistemas construye un andamiaje de servicios controlados con manejo de peticiones de servicios y soporte de tareas en estados de desconexión, lo que posibilita a los usuarios de dispositivos móviles pasar de ser simples usuarios “en movimiento” que realizan sus labores diarias y centralizan sus datos y avances en determinados momentos de la jornada diaria, a trabajadores móviles que no dependen de la infraestructura de red para colaborar, si no que según la disponibilidad de redes físicas o compañeros con los cuales interactuar, pueden compartir recursos, realizar actividades en conjunto o simplemente hacer trabajo individual. Los componentes desarrollados en este trabajo de título no se consideran, bajo ningún punto de vista, un trabajo cerrado. El trabajo a futuro o extensiones que puede aplicarse a este desarrollo incluye, entre muchos aspectos destacables, los siguientes puntos: • Implementar el sistema de roles planteado en esta memoria, con lo cual se puede “universalizar” el manejo de los roles para cada aplicación, donde cada una de ellas podría otorgar los privilegios que se estime conveniente a cada uno de los roles existentes dentro de una lista predefinida de ellos dentro del middleware, los cuales pueden ser expandidos por cada aplicación. • Establecer un sistema de prioridades para las peticiones administradas por el Service Manager, con lo cual se le puede dar más urgencia a algunas solicitudes de servicios, o 41 crear listas de espera cuando las peticiones tardan mucho en ser respondidas. Este tipo de sistema previene la ocurrencia de “cuellos de botella” cuando se realizan muchas peticiones, sobre todo entre equipos de distintas prestaciones, lo cual mejora considerablemente la usabilidad de las aplicaciones. • Agregar nuevos proveedores de almacenamiento, que optimicen las características de los distintos dispositivos hacen uso de este middleware. Esto permitiría crear aplicaciones que, según el tipo de dispositivo en que se ejecutan, escogen el proveedor de almacenamiento que les brinde un mejor desempeño. • Implementar algún protocolo de seguridad, ya que el MicroWebServer está capacitado para dotar a sus servicios de seguridad, pero hasta el momento esto no es aprovechado por los componentes desarrollados en esta memoria. También sería interesante expandir este trabajo con el desarrollo de aplicaciones que hagan uso de las bondades del middleware, para así descubrir nuevas necesidades que permitan realizar mejoras sobre sus componentes o agregar componentes nuevos a su estructura. 42 6. Bibliografía [Aldunate, 2006] Aldunate, R. Larson, G. Nussbaum, M. Ochoa, S.F., Herrera, O.: Understanding the Role of Mobile Ad-hoc Networks in Non-traditional Contexts. 8th IFIP/IEEE International Conference on Mobile and Wireless Communication Networks, Santiago Chile, Springer Science + Business Media. Vol. 211, (August 2006). [Arnold, 1999] Arnold, K., O’Sullivan, B., Scheifler, R., Waldo, J., Wollrath, A.: The Jini Specification. Addison-Wesley, (1999). [Beatty, 2004] Beatty, J. Kakivaya, G. Kemp, D., Lovering, B., Roe, B., Schlimmer, J., Simonnet, G., Weast, J.: Web Services Dynamic Discovery (WS-Discovery). Microsoft Press, (2004). [Bischof, 2003] Bischof, H., Kaminsky, A., Binder, J.: A new Framework for Building Secure Collaborative Systems in Ad Hoc Network. Proceedings of Ad-Hoc, Mobile, and Wireless Networks, Springer Verlag, (2003). [Bosneag, 2005] Bosneag, A.M., Brockmeyer, M.: GRACE: Enabling collaborations in wide-area distributed systems. Proc. of the 14th IEEE International Workshops on Enabling Technologies: Infrastructure for Collaborative Enterprise (WETICE), Workshop on Distributed and Mobile Collaboration (DMC), IEEE CS Press, Linkoping University Sweden, 72-77, (2005). [Brugnoli] Brugnoli, M.C., Davide, F., Slagter, R.: The future of mobility and of mobile services. Report of MOSAIC Project, http://mosaic-network.org [Buszko, 2001] Buszko, D., Lee, W., Helal, A.: Decentralized Ad-Hoc Groupware API and Framework for Mobile Collaboration. Proc. of ACM International Conference on Supporting Group Work (GROUP), ACM Press, Colorado USA, 5-14. (2001). [Carrasco, 2007] Carrasco, V.: Servicios Web en Dispositivos Móviles para el Soporte de Aplicaciones Colaborativas. Memoria de Ingeniero Civil en Computación. Departamento de Ciencias de la Computación, Universidad de Chile. (2007). [Chen, 2002] Chen, K., Shah, S. Nahrstedt, K.: Cross Layer Design for Data Accessibility in Mobile Ad Hoc Networks. IEEE Wireless Communications, Vol. 21, 49-75, (2002). [Foggon, 2004] Foggon, D. Maharry, D., Ullman, C., Watson, K.: Programming Microsoft .NET XML Web Services. Microsoft Press, (2004). [Gehlen, 2005] Gehlen, G., Pham, L.: Mobile Web Services for Peer-to-Peer Applications. Proc. of the 2nd IEEE Consumer Communications and Networking Conference, (CCNC), Las Vegas, USA. 427-433, (2005). [Handorean, 2003] Handorean, R., Payton, J., Julien, C., Roman, G.: Coordination Middleware Supporting Rapid Deployment of Ad Hoc Mobile Systems. Proc. of the 23rd International Conference on Distributed Computing Systems (ICDCS), Workshop on Mobile Computing Middleware (MCM), IEEE CS Press, Rhode Island USA, 363-368, (2003). 43 [Heinemann, 2003] Heinemann, A., Kangasharju, J., Lyardet, F., Mühlhäuser, M.: iClouds: Peer-toPeer Information Sharing in Mobile Environments. Pro of the 9th International Euro-Par Conference (Euro-Par), Springer, LNCS 2790, Klagenfurt Austria, 1038-1045, (2003). [Hirsch, 2006] Hirsch, F., Kemp, J., Ilkka, J.: Mobile Web Services: Architecture and Implementation. Nokia Research Center. John Wiley & Sons Publisher, (2006). [Jorstad, 2005] Jorstad, I., Dustdar, S. Thanh, D.V.: A Service Oriented Architecture Framework for Collaborative Services. Proc. of the 14th IEEE International Workshops on Enabling Technologies: Infrastructure for Collaborative Enterprise (WETICE'05), (2005). [JXTA, 2006] JXTA Project. URL: http://www.jxta.org. Última visita: Octubre (2006). [Lee, 2000] Lee B.: INSIGNIA: An IP-Based Quality of Service Framework for Mobile Ad-hoc Networks, Journal on Parallel and Distributed Computer., Special Issue on Wireless and Mobile Computing and Communications, Vol. 60 No. 4, April. 374-406, (2000). [Litiu, 2004] Litiu, R., Zeitoun, A.: Infrastructure Support for Mobile Collaboration. Proceedings of the 37th Annual Hawaii International Conference on System Sciences (HICSS'04), Hawaii, 5-8, (2004). [Macker, 1998] Macker, J. P., Corson, M. S.: Mobile Ad-hoc Networking and the IETF. ACM SIGMOBILE Mobile Computing and Communications Review Archive Vol. 2, Issue 1, January, (1998). [Marquès, 2005] Marquès, J., Navarro, L.: Autonomous and Self-sufficient Groups: Ad Hoc Collaborative Environments. Proc. of the 11th International Workshop on Groupware (CRIWG), Springer, LNCS 3706, Porto do Galinhas Brazil, 57-72, (2005). [Mascolo, 2002] Mascolo, C., Capra, L., Zachariadis, S., Emmerich, W.: XMIDDLE: A Data-Sharing Middleware for Mobile Computing. Journal on Personal and Wireless Communications 21(1), 77-103, (2002). [Meier, 2003] Meier, R., Cahil, V.: Exploiting Proximity in Event-based Middleware for Collaborative Mobile Applications. In Proceedings of the 4th IFIP International Conference on Distributed Applications and Interoperable Systems (DAIS’03), Paris, France, (2003). [Meissner, 2003] Meissner, A., Babu Musunoori, S.: Group Integrity Management Support for Mobile Ad-Hoc Communities. Proc. of the 1st Workshop on Middleware for Pervasive and Ad Hoc Computing, (2003). [Microsoft, 2004] Microsoft Corp. Pattern & Practices: Smart Client Application Block. URL: http://msdn.microsoft.com/library/default.asp?url=/library/enus/dnpag/html/offline.asp. (Febrero 2004) Última Visita: Junio (2007). [Nemlekar, 2001] Nemlekar, M.: Scalable Distributed Tuplespaces. MSc. Thesis. Department of Electrical and Computer Engineering, North Carolina State University, Chapter 5, (2001). 44 [Neyem, 2005] Neyem, A., Ochoa, S. Guerrero, L, Pino, J.: Sharing Information Resources in Mobile Ad-hoc Networks. Proc. of International Workshop on Groupware (CRIWG), LNCS 3706, Springer-Verlag. Sept.., 351-358. (2005). [Neyem, 2006a] Neyem, A., Ochoa, S., Pino, J.: A Strategy to Share Documents in MANETs using Mobile Devices. 8th IEEE International Conference on Advanced Communication Technology (ICACT 2006), IEEE Communication Society, Phoenix Park, Korea, (February 2006). [Neyem, 2006b] Neyem, A., Ochoa, S. F., Pino, J.A.: Supporting Mobile Collaboration with ServiceOriented Mobile Units. Lecture Notes in Computer Science, vol. to appear. Heidelberg, Springer-Verlag, (2006). [Pashtan, 2005] Pashtan, A.: Mobile Web Services. Cambridge University Press, (2005). [Procopio, 2002] Procopio, M.J.: YCab.NET: Decentralized Collaboration Groupware for Mobile Devices using the MS .NET Framework. Master's of Science Thesis, University of Florida. (2002). Available at http://etd.fcla.edu/UF/UFE1000155/procopio_m.pdf [Sen, 2004] Sen, R., Handorean, R., Roman,G.C., Gill, C.: Service Oriented Computing Imperatives in Ad Hoc Wireless Settings (Book Chapter). Service-Oriented Software System Engineering: Challenges and Practices, (2004). [Schaffers, 2006] Schaffers, H., Brodt, T., Pallot,M., Prinz, W. (eds).: The Future Workplace Perspectives on Mobile and Collaborative Working. Mosaic Consortium, Telematica Instituut, The Netherlands, (2006). [Wyckoff, 1998] Wyckoff, P., McLaughry, S., Lehman, T., Ford, D.: T-Spaces. IBM Systems Journal, Vol. 37, No. 3, 454-474, (1998). 45 Apéndice A. Código Fuente A continuación se describe parte del código fuente de los componentes tecnológicos que forman parte de este trabajo de título. A1. Infraestructura Offline • FileSharingTestForm public partial class FileSharingTestForm : Form { private OfflineBlockBuilder obb; private FileSharingTestSA fileSharingTestSA; private bool isOnline = true; public FileSharingTestForm() { InitializeComponent(); } private void btnListFiles_Click(object sender, EventArgs e) { if (this.tbxServer.Text.Trim() != "" && this.tbxSource.Text.Trim() != "") { Cursor.Current = Cursors.WaitCursor; this.lblMessage.Text = "Waiting info..."; string serverUrl = "http://" + this.tbxServer.Text.Trim() + "/ FileSharingMobileService.asmx"; this.fileSharingTestSA.GetFileNames(serverUrl, this.tbxSource. Text.Trim()); } else MessageBox.Show("The fields 'Server' and 'Source' are both req uired."); } private void btnGetFiles_Click(object sender, EventArgs e) { if (this.tbxServer.Text.Trim() != "" && this.tbxDestination.Text.T rim() != "") { if (Directory.Exists(this.tbxDestination.Text.Trim())) { List<string> files = new List<string>(); for (int i = 0; i < this.lvwFiles.Items.Count; i++) { if (this.lvwFiles.Items[i].Checked) files.Add(((FileShareInfo)this.lvwFiles.Items[i].T ag).Fullname); } 46 if (files.Count > 0) { Cursor.Current = Cursors.WaitCursor; this.lblMessage.Text = "Retrieving files..."; string serverUrl = "http://" + this.tbxServer.Text.Tri m() + "/FileSharingMobileService.asmx"; this.fileSharingTestSA.GetFiles(serverUrl, files.ToArr ay(), this.tbxDestination.Text.Trim()); } else MessageBox.Show("You must select one or more items."); } else MessageBox.Show("The destination directory does not exist. "); } else MessageBox.Show("The fields 'Server' and 'Destination' are bot h required."); } private void FileSharingTestForm_Load(object sender, EventArgs e) { System.Threading.Thread.CurrentThread.Name = "main"; this.obb = OfflineBlockBuilder.Instance; this.obb.ConnectionManager.ConnectionStateChangedEvent += new Conn ectionStateChangedEventHandler(ConnectionManager_ConnectionStateChangedEvent); this.obb.Start(); this.fileSharingTestSA = new FileSharingTestSA(); this.fileSharingTestSA.FileNamesReadyEvent += new FileNamesReadyEv entHandler(fileSharingTestSA_FileNamesReadyEvent); this.fileSharingTestSA.FilesReadyEvent += new FilesReadyEventHandl er(fileSharingTestSA_FilesReadyEvent); this.fileSharingTestSA.ReportErrorEvent += new ReportErrorEventHan dler(fileSharingTestSA_ReportErrorEvent); this.fileSharingTestSA.Cargar(); } private void FileSharingTestForm_Closed(object sender, EventArgs e) { this.fileSharingTestSA.Guardar(); this.obb.Stop(); } void fileSharingTestSA_FileNamesReadyEvent(object sender, FileNamesRea dyEventArgs e) { if (System.Threading.Thread.CurrentThread.Name != "main") this.Invoke(new FileNamesReadyEventHandler(fileSharingTestSA_F ileNamesReadyEvent), new object[] { sender, e }); else { FileShareInfo[] files = (FileShareInfo[])e.GetResults; this.lvwFiles.Items.Clear(); if (files.Length > 0) { 47 foreach (FileShareInfo file in files) { ListViewItem lvi = new ListViewItem(file.Fullname + " - " + file.Length + " bytes"); lvi.Tag = file; lvi.Text = Path.GetFileName(file.Fullname) + " - " + file.Length + " bytes"; this.lvwFiles.Items.Add(lvi); } this.btnGetFiles.Enabled = true; } else MessageBox.Show("There is no files to show."); Cursor.Current = Cursors.Default; this.lblMessage.Text = "Done!"; } } void fileSharingTestSA_FilesReadyEvent(object sender, FilesReadyEventA rgs e) { if (System.Threading.Thread.CurrentThread.Name != "main") this.Invoke(new FilesReadyEventHandler(fileSharingTestSA_Files ReadyEvent), new object[] { sender, e }); else { Cursor.Current = Cursors.Default; this.lblMessage.Text = "Download Succeeded!"; } } void fileSharingTestSA_ReportErrorEvent(object sender, ReportErrorEven tArgs e) { if (System.Threading.Thread.CurrentThread.Name != "main") this.Invoke(new ReportErrorEventHandler(fileSharingTestSA_Repo rtErrorEvent), new object[] { sender, e }); else { Cursor.Current = Cursors.Default; MessageBox.Show(e.FailureReason); } } void ConnectionManager_ConnectionStateChangedEvent(object sender, Conn ectionStateChangedEventArgs e) { } private void btnChangeState_Click(object sender, EventArgs e) { if (isOnline) { this.obb.ConnectionManager.GoOffline(); this.btnChangeState.Text = "Offline"; this.isOnline = false; } else 48 { this.obb.ConnectionManager.GoOnline(); this.btnChangeState.Text = "Online"; this.isOnline = true; } } } • FileSharingTestSA public class FileSharingTestSA : ServiceAgent { private OfflineBlockBuilder offlineBlockBuilderInstance; public event FileNamesReadyEventHandler FileNamesReadyEvent; public event FilesReadyEventHandler FilesReadyEvent; public event ReportErrorEventHandler ReportErrorEvent; public FileSharingTestSA() { offlineBlockBuilderInstance = OfflineBlockBuilder.Instance; } public void GetFileNames(string serverURL, string path) { string onlineProxyAssemblyName = "FileSharingTest"; string onlineProxyClassName = "FileSharingTest.OnlineProxy"; string onlineProxyMethodName = "GetFileNames"; string specificServiceAgentMethodTobeInvoked = "FileNamesReady"; OnlineProxyContext onlineProxyMethodContext = new OnlineProxyConte xt(onlineProxyAssemblyName, onlineProxyClassName, onlineProxyMethodName); ServiceAgentContext specificServiceAgentContext = new ServiceAgent Context(specificServiceAgentMethodTobeInvoked); Payload messageToEnqueue = new Payload(onlineProxyMethodContext, this.Guid, specificServiceAgentContext, new string[] { serverURL, path }); offlineBlockBuilderInstance.PayloadConsumer.Enqueue(messageToEnque ue); } public void GetFiles(string serverURL, string[] files, string destinat ion) { string string string string onlineProxyAssemblyName = "FileSharingTest"; onlineProxyClassName = "FileSharingTest.OnlineProxy"; onlineProxyMethodName = "GetFiles"; specificServiceAgentMethodTobeInvoked = "FilesReady"; OnlineProxyContext onlineProxyMethodContext = new OnlineProxyConte xt(onlineProxyAssemblyName, onlineProxyClassName, onlineProxyMethodName); ServiceAgentContext specificServiceAgentContext = new ServiceAgent Context(specificServiceAgentMethodTobeInvoked); Payload messageToEnqueue = new Payload(onlineProxyMethodContext, this.Guid, specificServiceAgentContext, new object[] { serverURL, files, desti 49 nation }); offlineBlockBuilderInstance.PayloadConsumer.Enqueue(messageToEnque ue); } public void FileNamesReady(Payload referencePayload) { if (FileNamesReadyEvent != null) { FileNamesReadyEventArgs args = new FileNamesReadyEventArgs(ref erencePayload.Results); FileNamesReadyEvent(this, args); } } public void FilesReady(Payload referencePayload) { if (FilesReadyEvent != null) { FilesReadyEventArgs args = new FilesReadyEventArgs(); FilesReadyEvent(this, args); } } override public void ReportError(Payload refPayload) { string failureReason = ""; failureReason += "Error occurred in message execution, " + "the message won't be re-queued \n \n"; if (refPayload.FailureReason.GetType() == typeof(System.Web.Servic es.Protocols.SoapException)) { System.Text.RegularExpressions.MatchCollection mc = System.Tex t.RegularExpressions.Regex.Matches(refPayload.FailureReason.Message, "---> ([^ :]+):"); if (mc.Count >= 1 && mc[0].Groups[1].Value == "System.Data.DBC oncurrencyException") { failureReason += "This error may be because the local cach e and the data on the server are not in sync. Please download the data again. \n \n"; } } failureReason += refPayload.FailureReason.Message; refPayload.ClearResults(); if (ReportErrorEvent != null) { ReportErrorEventArgs args = new ReportErrorEventArgs(); args.FailureReason = failureReason; ReportErrorEvent(this, args); } } public void Guardar() 50 { offlineBlockBuilderInstance.PayloadConsumer.Save(); } public void Cargar() { offlineBlockBuilderInstance.PayloadConsumer.Load(); } } • OnlineProxy public class OnlineProxy { private FileSharingProxy proxy; public OnlineProxy() { } public Payload GetFileNames(Payload referencePayload) { try { string url = ((string[])referencePayload.RequestData)[0]; string path = ((string[])referencePayload.RequestData)[1]; this.proxy = new FileSharingProxy(url); referencePayload.Results = this.proxy.GetFileNames(path); return referencePayload; } catch (Exception e) { referencePayload.RecordFailure(e); return referencePayload; } } public Payload GetFiles(Payload referencePayload) { try { string url = (((object[])referencePayload.RequestData)[0]).ToS tring(); string[] files = (string[])((object[])referencePayload.Request Data)[1]; string destination = (((object[])referencePayload.RequestData) [2]).ToString(); if (destination.LastIndexOf(Path.DirectorySeparatorChar) != destination.Length - 1) destination += Path.DirectorySeparatorChar; this.proxy = new FileSharingProxy(url); this.proxy.GetFiles(files); 51 for (int i = 0; i < this.proxy.ResponseAttachments.Count; i++) { string file = files[i]; string filename = Path.GetFileName(file); _Save(destination + filename, ((DimeAttachment)this.proxy. ResponseAttachments[i]).DimeData); } return referencePayload; } catch (Exception e) { referencePayload.RecordFailure(e); return referencePayload; } } private bool _Save(string path, byte[] data) { FileStream fileStream; try { fileStream = new FileStream(path, FileMode.Create, FileAccess.Write); } catch (UnauthorizedAccessException e) { System.Windows.Forms.MessageBox.Show("Unauthorized Access " + e.Message); return false; } BinaryWriter binaryWriter = new BinaryWriter(fileStream); binaryWriter.Write(data); binaryWriter.Close(); fileStream.Close(); return true; } } [System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://tempuri.org /")] public partial class FileShareInfo { private string _Fullname; public string Fullname { get { return _Fullname; } set { _Fullname = value; } } private long _Length; public long Length { get { return _Length; } set { _Length = value; } 52 } } • FileSharingProxy [WebServiceBinding(Name = "FileSharingSoap", Namespace = "http://tempuri.o rg")] public class FileSharingProxy : MobileWebServerClientProtocol { public FileSharingProxy(string serverURL) { this.Url = serverURL; } [MobileWebServerExtension] [SoapHeader("SecurityHeader")] [SoapDocumentMethodAttribute("http://tempuri.org/GetFileNames", Reques tNamespace = "http://tempuri.org/", ResponseNamespace = "http://tempuri.org/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = SoapParameterStyle.Wrapped)] public FileShareInfo[] GetFileNames(string path) { object[] results = this.Invoke("GetFileNames", new object[] { path }); return ((FileShareInfo[])(results[0])); } [SoapDocumentMethodAttribute("http://tempuri.org/GetFiles", RequestNam espace = "http://tempuri.org/", ResponseNamespace = "http://tempuri.org/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = Soa pParameterStyle.Wrapped)] [MobileWebServerExtension] [SoapHeader("SecurityHeader")] public void GetFiles(string[] files) { this.Invoke("GetFiles", new object[] { files }); } } • Events public delegate void FileNamesReadyEventHandler(object sender, FileNamesRe adyEventArgs e); public delegate void FilesReadyEventHandler(object sender, FilesReadyEvent Args e); public delegate void ReportErrorEventHandler(object sender, ReportErrorEve ntArgs e); public class FileNamesReadyEventArgs : EventArgs { private object results; public object GetResults { get { return results; } } 53 public FileNamesReadyEventArgs(object refResults) { results = refResults; } } public class FilesReadyEventArgs : EventArgs { public FilesReadyEventArgs() { } } public class ReportErrorEventArgs : EventArgs { private string reason; public string FailureReason { get { return reason; } set { reason = value; } } public ReportErrorEventArgs() { } } A2. Proveedores de Almacenamiento • IQueueStorageProvider public interface IQueueStorageProvider { int Size { get; } void Enqueue(QueueMessage queueMessage); QueueMessage Dequeue(); void Flush(); void Save(); void Load(); } • QueueStorageProvider public abstract class QueueStorageProvider : IQueueStorageProvider, IProvi der { public abstract int Size { get; } 54 protected QueueStorageProvider() { } public void Initialize(XmlNode parameters) { DoLocalSetup(parameters); Initialize(); } public void Enqueue(QueueMessage queueMessage) { byte [] msgBytes = StreamingUtils.ToBytes(queueMessage); DoEnqueue(msgBytes); } public QueueMessage Dequeue() { byte [] dequeuedBytes = DoDequeue(); QueueMessage msg = new QueueMessage(new Payload(null, GuidEx.Empty , null, null)); return StreamingUtils.ToObject(dequeuedBytes,msg.GetType()); } public abstract void Flush(); protected void ValidateConfigurationParameter(string parameterName, string parameterValue, XmlNode parameterNode) { if(parameterValue.Length == 0) { if(parameterName.Substring(0,1)!="@") parameterName="@"+parameterName; XmlNode offendingNode = XPath.GetChildNodeFromParent(parameter Node,parameterName); throw new ConfigurationException(String.Format(ProvidersResour ceTable.GetString(ProvidersResourceTable.InvalidOrMissingAttributeInConfigFile ), parameterName), offendingNode); } } protected void ValidateConfigurationCustomValue(string customElementNa me, string customValue, XmlNode parameterNode) { if(customValue.Length == 0) { if(customElementName.Substring(0,1)!="@") customElementName="@"+customElementName; XmlNode offendingNode = XPath.GetChildNodeFromParent(parameter Node,customElementName); throw new ConfigurationException(String.Format(ProvidersResour ceTable.GetString(ProvidersResourceTable.InvalidOrMissingElementInConfigFile), customElementName), offendingNode); } } 55 protected abstract void DoEnqueue(byte[] objectToStream); protected abstract byte[] DoDequeue(); protected abstract void DoLocalSetup(XmlNode parameters); protected abstract void Initialize(); private bool GetBooleanAttribute(XmlNode parameters, string parameterName) { if(parameterName.Substring(0,1)!="@") parameterName="@"+parameterName; string parameterStringValue = XPath.GetChildNodeFromParent(paramet ers,parameterName).InnerText; ValidateConfigurationParameter(parameterName, parameterStringValue , parameters); try { return bool.Parse(parameterStringValue); } catch(FormatException e) { throw new ConfigurationException(String.Format(ProvidersResour ceTable.GetString(ProvidersResourceTable.InvalidFieldFormatInConfigFile), para meterName), e); } } public void Save() { DoSave(); } protected abstract void DoSave(); public void Load() { DoLoad(); } protected abstract void DoLoad(); } • InMemoryQueueStorageProvider public class InMemoryQueueStorageProvider : QueueStorageProvider { private Queue queuedMessages = new Queue(); public override int Size { get { return queuedMessages.Count; }} public InMemoryQueueStorageProvider() { 56 } public InMemoryQueueStorageProvider(bool isEncrypted, bool isSigned) { } public override void Flush() { queuedMessages.Clear(); } override protected byte[] DoDequeue() { return queuedMessages.Dequeue() as byte[]; } override protected void DoEnqueue(byte[] objectStream) { queuedMessages.Enqueue(objectStream); } protected override void DoLocalSetup(XmlNode parameters) { ; } protected override void Initialize() { ; } protected override void DoSave() { XmlDocument xml = new XmlDocument(); XmlNode root = xml.CreateElement("messages"); while (this.queuedMessages.Count > 0) { XmlNode message = xml.CreateElement("message"); byte[] serializedMessage = this.queuedMessages.Dequeue() as byte[]; string serializedMessageString = ""; for (int i = 0; i < serializedMessage.Length; i++) { serializedMessageString += serializedMessage[i] + " "; } message.InnerText = serializedMessageString.Trim(); root.AppendChild(message); } xml.AppendChild(root); string currentDirectory = Path.GetDirectoryName(Assembly.GetExecut ingAssembly().GetModules()[0].FullyQualifiedName); xml.Save(currentDirectory + "\\queue.xml"); } protected override void DoLoad() { XmlDocument xml = new XmlDocument(); 57 string currentDirectory = Path.GetDirectoryName(Assembly.GetExecut ingAssembly().GetModules()[0].FullyQualifiedName); if (!File.Exists(currentDirectory + "\\queue.xml")) return; xml.Load(currentDirectory + "\\queue.xml"); XmlNodeList messages = xml.SelectSingleNode("messages").SelectNode s("message"); foreach (XmlNode message in messages) { string serializedMessageString = message.InnerText; string[] stringBytes = serializedMessageString.Split(new char[] { ' ' }); byte[] serializedMessage = new byte[stringBytes.Length]; for (int i = 0; i < stringBytes.Length; i++) { serializedMessage[i] = Convert.ToByte(stringBytes[i]); } QueueMessage msg = new QueueMessage(new Payload(null, GuidEx.E mpty, null, null)); QueueMessage queueMessage = StreamingUtils.ToObject(serialized Message, msg.GetType()); base.Enqueue(queueMessage); } } } A3. Administrador de Perfiles • ProfileManager public class ProfileManager { private static ProfileManager profileManager; private Guid unitId; private string unitPlatform; private DateTime lastUpdate; public static ProfileManager Instance { get { if (profileManager == null) { profileManager = new ProfileManager(); } return profileManager; } } public Guid UnitId { 58 get { return Instance.unitId; } } public string UnitPlatform { get { return Instance.unitPlatform; } } public DateTime LastUpdate { get { return Instance.lastUpdate; } } private ProfileManager() { XmlDocument xml = new XmlDocument(); string currentDirectory = Path.GetDirectoryName(Assembly.GetExecut ingAssembly().GetModules()[0].FullyQualifiedName); FileInfo fi = new FileInfo(currentDirectory + "\\profile.xml"); if (fi.Exists) { xml.Load(fi.FullName); XmlNode root = xml.SelectSingleNode("profile"); this.unitId = new Guid(root.SelectSingleNode("unit_id").InnerT ext); this.unitPlatform = root.SelectSingleNode("unit_platform").Inn erText; this.lastUpdate = DateTime.Parse(root.SelectSingleNode("last_u pdate").InnerText); } else { XmlNode root = xml.CreateElement("profile"); XmlNode id = xml.CreateElement("unit_id"); this.unitId = Guid.NewGuid(); id.InnerText = this.unitId.ToString(); root.AppendChild(id); XmlNode platform = xml.CreateElement("unit_platform"); this.unitPlatform = Environment.OSVersion.Platform.ToString(); platform.InnerText = this.unitPlatform; root.AppendChild(platform); XmlNode update = xml.CreateElement("last_update"); this.lastUpdate = DateTime.Now; update.InnerText = this.lastUpdate.ToString(); root.AppendChild(update); xml.AppendChild(root); xml.Save(fi.FullName); } } } 59