jueves, 14 de junio de 2012

Primeros pasos con Delphi DataSnap 2009


Fuente Original: Delphi y Datasnap

Resumen: Instrucciones paso a paso para hacer un "Hola Mundo" con Datasnap 2009

Introducción

Una de las principales novedades de RAD Studio 2009 es el framework DataSnap 2009 para la creación de aplicaciones de base de datos multicapas. De hecho DataSnap 2009 es más que eso. Se trata de una arquitectura basada en componentes para la creación de aplicaciones arbitrarias que se comunica a través de la red. Nunca había sido tan fácil crear rápidamente aplicaciones de servidor y cliente en Delphi y C++ Builder!

La nueva arquitectura DataSnap 2009 amplía el framework de drivers para bases de datos DBX4 introducidos en Delphi 2007 y C++ Builder 2007. El framework DBX4 abstrae de la idea de un controlador de base de datos e introduce el concepto de tipos de comandos extensible. DataSnap 2009 se aprovecha de la extensibilidad DBX4 y se suma a la cartera de las actuales drivers de bases de datos con el nuevo driver "DataSnap" que - desde la perspectiva de una aplicación cliente - se parece mucho a una base de datos, pero en realidad ofrece conectividad a una aplicación de servidor DataSnap. Asimismo, el nuevo tipo de comando "DSServerMethod" para invocar los métodos de los objetos de servidor se ha añadido a la "clase TDBXCommandTypes".

El DataSnap 2009 es parte de la biblioteca de componentes visuales (VCL) que es compartida entre Delphi y C++ Builder. En este artículo me voy a centrar en Delphi 2009, sin embargo, la casi totalidad de la funcionalidad descrita aquí también es aplicable a C++ Builder 2009.

"Hola Mundo" con DataSnap 2009

Te voy a encaminar por los pasos para la construcción de un simple "Hola Mundo" con DataSnap 2009 que constará de un servidor y una aplicación de cliente. La aplicación de servidor proporcionará la función "Echo" que acepta una cadena y devuelve una cadena que se hace eco del valor original. La aplicación cliente proporcionará los medios para entrar una cadena arbitraria, llame a la función "Echo" con una cadena siempre y muestre la cadena devuelta desde el servidor. Demasiado simple? Sí ... pero un buen punto de partida para cosas más complejas!

¿Estás listo? ¿Esta tu Delphi 2009 ya instalado e iniciado? Sino tienes instalado Delphi 2009 lo puedes obtener en http://www.codegear.com/products/delphi/win32 y dale a la mejor versión de Delphi un intento!

Pasos para la construcción del Servidor de Aplicaciones con DataSnap 2009

Crear un nuevo proyecto Delphi (o C++Builder) de tipo "VCL Forms Application", haga clic en "Save All" en el menu "Files". Guardar la unidad del formulario principal como "uFormServer" y el proyecto como "DelphiDataSnapEchoServer". En el Object Inspector cambiar la propiedad "Name" de la forma a "FormServer" y la propiedad "Caption" a "Delphi 2009 DataSnap Echo Server".

Ahora vamos a transformar esta aplicación Delphi estándar en un servidor DataSnap. Esto se hace con los componentes de la pestaña "DataSnap Server". Contiene tres componentes diferentes y necesitamos de todos ellos. Haga doble clic en los componentes "TDSServer", "TDSTCPServerTransport" y "TDSServerClass" en la paleta de herramientas para agregar a la forma de servidor.


Figura 1: Formulario principal del DataSnap Application Server

El componente "DSServer1" es la lógica central del servidor de aplicaciónes DataSnap. Contiene los métodos "Start" y "Stop" para iniciar y detener el servidor, y también una propiedad muy útil "autostart". Por defecto está establecido en "True", de modo que el servidor se inicia automáticamente en el inicio de la aplicación. Sólo se necesita un componente "TDSServer" por servidor de aplicaciones.

El componente "DSTCPServerTransport1" contiene un componente Indy "TIdTCPServer" que implementa un servidor TCP multihilo para escuchar las conexiones entrantes de los clientes en varios subprocesos. Este componente no tiene ningún tipo de eventos, pero contiene una propiedad "Server" que necesita ser ajustada al "DSServer1". También tiene una propiedad "Port" que indica el puerto TCP que se utilizará. Por defecto está configurado para el puerto 211.

El componente "DSServerClass1" representa... sí... tienes razón... una clase de servidor :-) También tiene la propiedad "Server" que debe ser ajustada a "DSServer1". De esta manera, los tres componentes están unidos entre sí. El componente "TDSServerClass" contiene el evento "OnGetClass" que debe ser implementado por el programador. Si no se implementa este evento, la aplicación inmediatamente después del inicio genera un evento TDBXError con el mensaje "OnGetClass event not set or it did not provide a class reference". El evento "OnGetClass" tiene el argumento "PersistentClass" que se pasa por referencia. En el manejador de evento el programador tiene que asignar al "PersistentClass" una referencia de clase a una clase de servidor. Esto es probablemente un concepto muy importante a comprender acerca de la arquitectura de la DataSnap 2009. Estamos asignando a "PersistentClass" una "referencia de clase" y no una "referencia de objeto".

El servidor de DataSnap automáticamente crea y destruye instancias de clases del servidor. La creación de instancias de una clase de servidor es controlada por la propiedad "TDSServerClass.LifeCycle" que puede tener uno de los tres posibles valores: "Server", "Session" e "Invocation".

El ciclo de vida ajustado en "Server" significa que el servidor DataSnap creará una instancia de una clase de servidor que será utilizado por todos los clientes conectados a la aplicación de servidor. Esto representa un patrón "Singleton". Tenga cuidado al usar el ciclo de vida "Server" como la implementación de servidor de clase tiene que ser thread-safe, ya que es posible que este objeto singleton se accedá al mismo tiempo por varios subprocesos.

El valor por defecto del "LifeCycle" es "Session". Esto significa que el servidor DataSnap creará una instancia de una clase de servidor para cada cliente conectado. Esto es similar al concepto de un session bean "stateful" de JEE.

El tercer valor posible de propiedad "LifeCycle" es "Invocación". Una instancia de la clase de servidor se crea y se destruye por cada llamada al método que llegan de un cliente y el estado de una clase de servidor no se conservan entre llamadas a métodos.

Con el fin de implementar el evento "OnGetClass" tenemos que añadir a nuestro proyecto de servidor de DataSnap una clase de servidor. Seleccione "File | New | Other" del menú "File" y haga doble clic en el icono "Server Module" de la categoría "Delphi Files".


Figura 2: Nuevo DataSnap 2009 "Server Module"

Esto agregará un nuevo módulo servidor para el proyecto. Guardar la nueva unidad como "uServerModule". En este momento voy hacer un paso opcional que tiene como objetivo destacar el hecho de que es el servidor quien gestiona el ciclo de vida de los objetos de servidor. El módulo de servidor se deriva en última instancia de un módulo de datos y el diseñador de Delphi lo añade automáticamente a una lista de formas auto-creadas en nuestra aplicación de servidor. Esto es innecesario, por lo que puede ir al diálogo "Project | Options" y eliminar el "DSServerModule1" de la lista de formas auto-creadas en la sección "formas".


Figura 3: El DSServerModule1 no tiene que ser auto-creado.

También es seguro para comentar la variable global "DSServerModule1: TDSServerModule" de la unidad del módulo servidor ya que nunca se utiliza.

Ahora vamos a imlpementar una función simple "Echo" que acepta una cadena y devuelve una cadena. Voy ha implementar la funcionalidad de echo con una fortaleza empresarial para que mi aplicación no solo haga un eco del argumento sino dos ;-) El módulo de servidor de aplicación resultante tiene este aspecto:


Figura 4: Implementación del módulo servidor DataSnap Echo.

El último paso es implementar el evento "DSServerClass1.OnGetClass". En la forma principal del servidor, seleccione el componente "DSServerClass1" y en el Inspector de Objetos haga doble clic en el evento "OnGetClass" para generar un manejador vacío. Añadir "uServerModule" a la cláusula "uses" de la forma principal e implementar el evento.


Figura 5: Código del evento DSServerClass1.OnGetClass.

Nuestro servidor de aplicación DataSnap eco ha finalizado.

Las aplicaciones cliente y servidor necesitan una pieza de conocimiento compartido para comunicarse.

Si desea tener dos aplicaciones arbitrarias para comunicarse debe haber alguna forma de contrato en el lugar que describe lo que la funcionalidad de un cliente puede tener acceso a un servidor. Diferentes tecnologías de computación distribuida tienen diferentes maneras de resolver este problema. En CORBA, el contrato se describe en la forma de lenguaje de definición de interfaces (IDL) del documento, en DCOM es una biblioteca de tipos. En Servicios Web tenemos un Web Service Description Language (WSDL) que es utilizado por las aplicaciones de cliente para generar proxies. DataSnap 2009 no tiene ningún tipo de forma estática de una descripción de servicio. Con el fin de crear un cliente DataSnap necesita tener acceso a una aplicación de servidor que se ejecuta en tiempo de diseño. Esto es similar a los servicios Web donde el documento WSDL puede por lo general ser obtenido al vuelo de una aplicación de servicios Web en ejecución.

Pasos para la construcción de aplicaciones cliente con DataSnap 2009

La aplicación DataSnap Server ya está abierta en el IDE de Delphi y lo más conveniente es agregar una aplicación cliente a un grupo de proyecto para que podamos cambiar entre dos proyectos dentro del IDE.

Haga clic derecho en el "ProjectGroup1" en el Administrador de proyectos, seleccione "Add New Project" en el menú contextual y seleccionar un nuevo proyecto Delphi "VCL Forms Application". Guardar todos con el menú "File". Guarde la unidad de la forma principal como "uFormClient", el proyecto como "DelphiDataSnapEchoClient" y el grupo de proyecto como "DelphiDataSnapEchoGrp". Haga clic en algún lugar de la forma para asegurarse de que está seleccionado en el Inspector de Objetos. Cambiar la propiedad "Name" con el valor "FormClient" y la propiedad "Caption" con "Delphi 2009 DataSnap Echo Client".

Sólo puede tener un proyecto activo en cualquier punto dado del tiempo en RAD Studio IDE. El Project Manager indica el proyecto activo, mostrando el nombre del proyecto con negrita. También puede ver el nombre del proyecto activo en el título de la ventana de RAD Studio. Haga doble clic en el nombre del proyecto en el Project Manager para que el proyecto quede activo.

Durante el desarrollo de una aplicación cliente DataSnap necesitamos tener acceso a una instancia en ejecución de la aplicación de servidor. Haga doble clic en el "DelphiDataSnapEchoServer.exe" en el Project Manager para activarla y seleccione "Run | Run Without Debugging" en el menú principal para ejecutar la aplicación de servidor. La necesitamos tener funcionando mientras se desarrolla el cliente. Puede minimizar la ventana de aplicación de servidor. Haga doble clic en el "DelphiDataSnapEchoClient.exe" en el Project Manager para volver a la aplicación cliente.

Como se indicó anteriormente DataSnap 2009 amplía la arquitectura de drivers de base de datos DBX4 implementando el driver especial "DataSnap" que desde la perspectiva de un cliente se parece a una conexión a una base de datos, pero en realidad ofrece conectividad a servidores DataSnap. Esa es la razón por la que empezamos el desarrollo del cliente con un componente "SQLConnection". Asegúrese de que el formulario del cliente se abre en el IDE, ir a la Paleta de herramientas y haga doble clic en el componente "TSQLConnection" de la pestaña dbExpress para añadirlo a la forma. Ir al Inspector de Objetos, expanda la propiedad "Driver" y seleccione el driver "DataSnap". Tenga en cuenta que la propiedad "Driver" contiene ahora subpropiedades específicas de DataSnap. Asegúrese de que el "hostname" está ajustado a "localhost" (o el nombre de DSN o la dirección IP de la máquina donde se ejecuta el servidor) y el "Port" se establece en el número 211. La propiedad "Port" tiene que coincidir con el valor de la propiedad "DSTCPServerTransport1.Port" en la aplicación de servidor.

Además cambie la propiedad "SQLConnection1.LoginPrompt" a "False" para evitar que aparezca el dialogo de nombre de usuario y contraseña cada vez que nos conectamos con el servidor.

Haga clic derecho en el componente "SQLConnection1" en el formulario y seleccione "Generate DataSnap Client Classes" desde el menú contextual.


Figura 6: Generar clases de cliente DataSnap desde el menú contextual del SQLConnection1.

Esto añade una nueva unidad para el proyecto del cliente. Guardarla como "uClientClasses". La unidad generada contendrá la clase "TDSServerModule1Client" que puede ser utilizado para comunicarse con el servidor como si fuera un objeto local. DataSnap 2009 utiliza RTTI (El mecanismo "reflexión" de Delphi) para descubrir todos los métodos públicos y publicados en las clases de servidor y genera las clases de proxy coincidentes con firmas de método.

Con el fin de llamar a cualquier método de nuestro servidor es necesario crear una instancia de "TDSServerModule1Client" y llamar a su método "Echo" que toma y devuelve una cadena.

Cambie a "FormClient" y añadir a ella componentes "TButton" y "TEdit" de la paleta de herramientas. Añadir "uClientClasses" a la cláusula "uses" de la "FormClient" (por ejemplo, utilizando el menú "File | Use Unit"). Haga doble clic en el componente "Button1" y agregue el código siguiente al evento "onclick" generado. Esto creará una instancia de una clase de proxy, llame a su método "Echo" para pasar el contenido de la caja de edición y mostrar el resultado en un cuadro de diálogo.


Figura 7: Aplicación cliente DataSnap "Echo".

Tenga en cuenta que el constructor del "TDSServerModule1Client" requiere un argumento "TDBXConnection" que representa la el objeto de conexión DBX4 no-visual. Por suerte la clase "TSQLConnection" expone su "DBXConnection" interno como una propiedad pública para que podamos usarla en nuestro código.

¡Eso es! Simplemente ejecute el cliente, escriba algo en el cuadro de edición y haga clic en el botón para llamar el método "Echo" en el servidor y mostrar el resultado.


Figura 8: Cliente DataSnap "Echo" en acción.

Resumen

La arquitectura de DataSnap 2009 para crear aplicaciones multicapas de base de datos es una de las novedades más interesantes e innovadores introducidos en RAD Studio 2009. Puede ser utilizado no sólo para la construcción de aplicaciones de bases de datos, sino también para sistemas arbitrarios cliente/servidor que se comunican a través de la red utilizando el protocolo TCP. RAD Studio 2009 contiene Delphi 2009, C++ Builder 2009 para la construcción de aplicaciones con alto rendimiento, nativas de Windows y el Delphi Prism para la construcción de nuevas aplicaciones .NET. La tecnología DataSnap 2009 está disponible en todos estos entornos.

DataSnap 2009 es mucho más que eso. Además de devolver los tipos simples como "cadena" es posible pasar tipos más complejos, como una matriz o "TDataSet". El nuevo componente "TSqlServerMethod" se puede utilizar para llamar a métodos de servidor sin necesidad de generar las clases de clientes, y el nuevo componente "TDSProviderConnection" hace más fácil la creación de aplicaciones de bases de datos donde se pueden aplicar las actualizaciones de bases de datos desde el cliente al servidor. Con la subpropiedad "ServerConnection" del driver DataSnap "TSQLConnection.Driver" incluso es posible el acceso a la conexión de base de datos del servidor directamente desde el lado cliente. Esta funcionalidad es la clave para la construcción de clientes DataSnap administrados con Delphi Prism .NET que se comunican con servidores DataSnap Delphi nativo 2009 o C++ Builder 2009.

Tenga en cuenta que DataSnap 2009 es una característica de RAD Studio 2009 Enterprise y Architect. No está disponible en RAD Studio 2009 Professional.

La versión electrónica de las aplicaciones descritas en este artículo puede ser descargado desde el Embarcadero CodeCentral (http://cc.codegear.com/item/26535).