ExtendedVisualOtp

ExtendedVisualOtp
Información sobre la plantilla
Evo logo.jpg
Framework para el desarrollo de aplicaciones de cliente-servidor.
CreadorIvan Carmenates García
Lanzamiento inicial7 de diciembre, 2010
Última versión estable1.5
GéneroSoftware Framework
Sistemas Operativos compatiblesWindows, Unix
Sitio web
http://comunidades.uci.cu/projects/evo

ExtendedVisualOtp (EVO) Es un componente especializado en la comunicación cliente – servidor, orientado al desarrollo de aplicaciones de tiempo real, donde el factor productividad es elevado y el costo de producción bastante bajo. Ideal para pequeñas compañías con poca experiencia en este tipo de aplicaciones, que desean insertarse en este amplio mundo, que es, la interacción e intercambio de información a través de la red de una forma rápida y eficaz.

Introducción

El ExtendedVisualOtp (EVO) es un componente especializado en la comunicación cliente – servidor, implementado en los lenguajes de programación C Sharp (C#) de Microsoft y Erlang de Ericsson, orientado al desarrollo de aplicaciones de tiempo real, donde las aplicaciones servidoras son escritas en el lenguaje de programación Erlang, y las aplicaciones clientes en .Net.

El concepto principal de este componente, es el desarrollo de aplicaciones cliente - servidor, donde el factor productividad es elevado y el costo de producción bastante bajo. Ideal para pequeñas compañías con poca experiencia en este tipo de aplicaciones, que desean insertarse en este amplio mundo, que es, la interacción e intercambio de información a través de la red de una forma rápida y eficaz.

Con este componente se pueden escribir fácilmente aplicaciones de mensajería instantánea y redes sociales sobre el desktop, también es posible la creación de Juegos Masivos On Line. Utilizando el potencial que tiene Erlang para el manejo de la concurrencia y respuesta en tiempo real, es posible la creación de cualquier tipo de aplicación cliente – servidor, que requiera de la premisa de respuesta en tiempo real.

Esto se puede ver para entrar en calor con un pequeño ejemplo:

Ejemplo 1

Imagine que usted desea desarrollar una pequeña aplicación cliente y quiere realizar una petición “conocer mi saldo” a una aplicación servidora, y además ser notificado de la respuesta generada a través de esa petición.

Ilustración 1. Ejemplo 1: Interacción cliente – servidor.

Desarrollar este simple ejemplo en cualquier lenguaje de programación, sin la utilización de un componente facilitador, puede representar un largo trabajo. Sin embargo, utilizando la librería ExtendedVisualOtp.dll para el desarrollo de aplicaciones clientes y la plantilla para servidores, evo_template, pasa de ser un largo y agotador trabajo a uno simple y acogedor.

Respuesta del ejemplo 1 utilizando EVO

En la aplicación cliente, después de unas sencillas configuraciones visuales para los componentes ErlangServerInterface y ErlangServerRequest de la librería ExtendedVisualOtp.dll.

   // Para conectar con el servidor.
   erlangServerInterface1.Connect(); 
   // Para enviar una petición.
   erlangServerRequest1.Request(“Descripción de la petición”, object _mensaje);

Otra forma puede ser:

  erlangServerRequest1.Request(object _mensaje);
Ilustración 2. Configuración visual para los componentes ErlangServerInterface y ErlangServerRequest.

La respuesta a la petición anterior, puede llegar de forma asincrónica a través del evento OnReceive del componente ErlangServerRequest, o puede ser capturada de forma sincrónica utilizando la función WaitForReply() inmediatamente después de la petición, ejemplo:

   IRequestInfo reqinfo = erlangServerRequest1.Request(“conoce el salario”, new object[] {
       “ ‘conocer_mi_saldo’ ”, “Ivan Carmenates García”});
   
   IServerReply reply = reqinfo.WaitForReply();
   MessageBox.Show(reply.CSharpReply.ToString());

reqinfo es un objeto de IRequestInfo, que contiene la información de la petición que se realizó al servidor, permitiendo hacer algunas cosas con ella, tales como, bloquear el programa para esperar por la respuesta reqinfo.WaitForReply() o abortar la petición realizada reqinfo.AbortRequest().

reply es un objeto de IServerReply, que contiene la información necesaria para tratar la respuesta enviada por el servidor.

En caso de que usted desee recibir la respuesta de forma asincrónica, usted debe usar el evento OnReceive del componente ErlangServerRequest, y no utilizar la función WaitForReply(), ejemplo:

   // Para hacer la petición.
   IRequestInfo reqinfo = erlangServerRequest1.Request(“conoce el salario”, new object[] {
       “ ‘conocer_mi_saldo’ ”, “Ivan Carmenates García”});
Ilustración 3. Evento OnReceive del componente ErlangServerRequest.
   // Y para recibir los mensajes de forma asincrónica utilizando
   // el evento de la ilustración 3.
   OnReceiveErlangServerRequestMethodNameHere(IServerReply _reply)
   {
       switch(_reply.Description) {
           case “conoce el salario”:
               MessageBox.Show(_reply.CSharpReply.ToString());
               break;
       }
   }

Entonces, para escribir aplicaciones servidoras, usted debe editar la plantilla para servidores evo_template, y en el archivo llamado evo_request_handler.erl que se encuentra en la carpeta sources, a partir de la línea 28, parte: [USER FUNCTIONS TO MODIFY] escribir nuestro código. Para el caso del ejemplo 1 sería:

   {{conocer_mi_saldo, Nombre}, Pid, RequestInfo}->
       Reply = evo_db_module:obtener_saldo(Nombre), %% Esta función se implementa en otro módulo.
       Pid ! {reply, Reply, RequestInfo};

Esta es la sencilla forma con la cual se escriben aplicaciones cliente – servidor en EVO. Si usted se pregunta ¿Cómo es posible?, ¿Debe haber algo más?, la respuesta es simplemente, ¡esto es todo!. El componente EVO en su integridad, tanto la plantilla evo_template para desarrollar aplicaciones servidoras, como la librería ExtendedVisualOtp.dll para desarrollar las aplicaciones clientes, se encarga por usted de desarrollar todo el trabajo engorroso.

Usted simplemente se abstrae a que existe un cartero muy veloz y eficaz, al que usted puede llamar para que entregue sus cartas o mensajes a un destinatario determinado, que en este caso, es el servidor, el cual puede enviar también ese mensaje a las demás personas en todo el “mundo”, o a una persona en específico; si es programado de esa forma.

Enviando objetos

En EVO enviar objetos es tan fácil como pasar un objeto a un método por parámetro, con solo enviar el objeto como parámetro de la petición, ejemplo:

   class MiObjeto {
       string nombre;
       int id;
       void obtener_nombre() {
           return this.nombre;
       }
       void poner_nombre(string _nombre) {
           this.nombre = _nombre;
       }
   }
   MiObjeto obj = new MiObjeto ();
   obj.poner_nombre(“ExtendedVisualOtp”);
   
   // Para hacer la petición.
   erlangServerRequest1.Request(new object[] {“ enviar_mi_objeto’ ”,  obj);

Para recibirlo en otro cliente, si en el servidor se programa para que envíe el mismo mensaje a todos los demás clientes, es el mismo mecanismo de siempre pero casteando con la clase, ejemplo:

   MessageBox.Show((_reply.CSharpReply as MiObjeto).obtener_nombre());

Lo mismo pasa con cualquier objeto serializable, ejemplo:

   // Para hacer la petición.
   erlangServerRequest1.Request(new object[] {“ ‘enviar_imagen’ ”,
       new Image.FromFile(“c:\\prueba.jpg”));
   // Para recibir la imagen en otro cliente.
   if (_reply.Description == “enviar_imagen”) {
       pictureBox1.Image = _reply.CSharpReply as Image;

Funcionalidades de la ExtendedVisualOtp.dll

ConvertToCSharp

Es una clase utilitaria para convertir objetos Otp.Erlang.Object a objetos CSharp.

  • FromErlangObject(Otp.Erlang.Object _object)
Convierte términos Otp.Erlang.Object en términos CSharp, ejemplo:
Otp.Erlang.List: [lista] en CSharp List<object>
Otp.Erlang.Tuple: {tupla} en CSharp object[]
Otp.Erlang.Atom: ‘átomo’ en CSharp string: “ ‘átomo‘ ”
Un objeto Otp.Erlang.List: [1, {nombre, “Ivan”}] es convertido a un objeto CSharp List<object>:
new List<object>().AddRange(new object[] {1, new object[] { “ ‘nombre’ ”, “ExtendedVisualOtp” }})
  • FromErlangReply(Otp.Erlang.Object _replyObject)
Convierte una respuesta o mensaje del servidor en formato Otp.Erlang.Object a un objeto CSharp de IServerReply.

ConvertToErlang

Es una clase utilitaria para convertir objetos CSharp a objetos Otp.Erlang.Object.

  • ToErlangObject(object _object)
Convierte objetos CSharp a objetos Otp.Erlang.Object, ejemplo:
List<object> en Otp.Erlang.List: [lista]
object[] en Otp.Erlang.Tuple: {tupla}
string: “ ‘átomo’ ” en Otp.Erlang.Atom: ‘átomo’
  • ToErlangObjectFromString(string _object)
Crea de una cadena CSharp un objeto Otp.Erlang.Object, ejemplo:
“{nombre, \“Ivan\” , ’edad’, 26}” es convertido a un termino Erlang {nombre, “Ivan”, edad, 26}.

ErlangServerInterface

Es un componente para configurar los parámetros de conexión en orden de trabajar como interface con el servidor.

  • AutoTrace
Establece si los mensajes de comunicación con el servidor deben ser mostrados en la consola de debug.
  • Connect()
Intenta la conexión con el servidor.
  • ErlangCookie
Establece la contraseña para conectarse con el nodo servidor Erlang.
  • Disconnect()
Le desconecta del servidor.
  • IsConnected
Obtiene el estado de la conexión.
  • OnDisconnected
Evento que se dispara cuando se pierde la conexión con el servidor.
  • OnReceive
Evento que se dispara cuando un mensaje del servidor es recibido. El parámetro es el mensaje.
  • PingTimeOut
Establece el tiempo de espera para conectarse con el servidor.
  • RemoteAddress
Establece la dirección del servidor.
  • RemoteNodeName
Establece el nombre del nodo servidor.
  • RemoteProcessName
Establece el nombre del proceso en el servidor que maneja las peticiones de los clientes.
  • SetOwnerForm(Form _ownerForm)
Establece la forma propietaria del componente para la validación de los errores de cruzamiento de hilos. Al establecer una forma como propietaria, no se necesitará validar para esta forma el tratamiento de requerimiento de invocación if (this.InvokeRequired) this.Invoke(delegate method). En los eventos OnReceive y OnDisconnect de este componente.
  • SentToErlangServerRequest(ErlangServerRequest _erlangServerRequest, IServerReply _reply)
Permite re-direccionar los mensajes globales enviados por el servidor a una interface ErlangServerRequest dada.
  • ServerPort
Establece el puerto daemon para conectarse con el servidor Erlang.
  • StartEVOTestApplication()
Inicia la aplicación de pruebas EVO Test Application.
  • UseShortNames
Establece si el formato de nombres cortos para la dirección del servidor va a ser usando en la conexión, ejemplo de nombre corto pc5, ejemplo de nombre largo: pc5.evo.cu.
  • AllowReceiveClientImage
Propiedad que establece si se pueden recibir imágenes de clientes en su cliente receptor, esto se debe desactivar para problemas de seguridad, ya que si está activo puede ser blanco fácil de ataques, debido a que cualquier programador conectado al servidor puede enviarle una aplicación maliciosa y ser ejecutada en su pc. Esta opción está por defecto desactivada.

ErlangServerRequest

Es un componente para realizar peticiones al servidor, utilizando el componente ErlangServerInterface como interface de conexión.

  • AbortAllRequests()
Aborta todas las peticiones realizadas al servidor.
  • AbortAsyncRequests()
Aborta todas las peticiones del tipo Async (asincrónicas) realizadas al servidor.
  • AbortNormalRequests()
Aborta todas las peticiones del tipo Normal realizadas al servidor. Una petición del tipo Normal es una petición que espera porque se complete ella misma para retornar el control al programa, pero no espera por que la respuesta sea recibida, es a elección del programador esperar también por la respuesta utilizando la función WaitForReply() inmediatamente después de la petición.
  • AbortRequest(IRequestInfo _requestInfo)
Aborta una petición específica.
  • Description
Establece el valor para la descripción de la petición cuando se usan las funciones Request() o RequestAsync() sin parámetros.
  • Message
Establece el valor para el mensaje de la petición cuando se usan las funciones Request() o RequestAsync() sin parámetros.
  • ErlangServerInterface
Establece la interfaz de conexión.
  • OnReceive
Evento que se dispara cuando se recibe una respuesta a una petición realizada al servidor. El parámetro es la respuesta.
  • Request(string _description, object _message)
Realiza una petición del tipo Normal al servidor. Retorna un objeto IRequestInfo.
  • RequestAsync(string _description, object _message)
Realiza una petición del tipo Async al servidor. Una petición del tipo Async, es una petición que no espera por que sea completada ella misma para retornar el control al programa, tampoco espera por la respuesta. Este tipo de petición es realizada en un hilo independiente y no retorna ninguna información de petición IRequestInfo.
  • Request(object _message)
Realiza una petición del tipo Normal al servidor, extrayendo la descripción para la misma, del mismo mensaje. Retorna un objeto IRequestInfo.
  • RequestAsync(object _message)

Realiza una petición del tipo Async al servidor, extrayendo la descripción para la misma del mismo mensaje. No retorna ninguna información de petición IRequestInfo.

  • SetOwnerForm(Form _ownerForm)
Establece la forma propietaria del componente para la validación de los errores de cruzamiento de hilos. Al establecer una forma como propietaria, no se necesitará validar para esta forma el tratamiento de requerimiento de invocación if (this.InvokeRequired) this.Invoke(delegate method). En el evento OnReceive de este componente.
  • PublishClientImage()
Publica a todos los clientes conectados al servidor la imagen de su aplicación. Esto es una funcionalidad extra para programadores que desean compartir ideas de sus aplicaciones. Para ello el programador receptor debe tener una aplicación conectada al servidor. Y el programador transmisor con solo ejecutar esta función al estar conectado también al servidor, la aplicación que esté desarrollando es transfería y ejecutada en la pc del programador receptor.

IRequestInfo

Es una clase o interface que contiene información de las peticiones realizadas al servidor.

  • AbortRequest()
Aborta la petición a la que apunta el objeto IRequestInfo.
  • Description
Propiedad para obtener la descripción de una petición realizada al servidor.
  • Kind
Obtiene el tipo de petición realizada al servidor.
  • WaitForReply()
Espera por la respuesta de la petición para retornar el control al programa.
  • WaitForReply(int _timeout)
Espera por la respuesta de la petición para retornar el control al programa un tiempo especificado por el parámetro _timeout en milisegundos.
  • WasAnswered
Indica si la petición fue contestada.
  • WasMade
Indica si la petición fue realizada.

IServerReply

Es una clase o interfaz que contiene información acerca de la respuesta de una petición realizada.

  • CSharpReply
Contiene la respuesta en formato de objeto CSharp.
  • Description
Contiene la descripción de la petición que generó esta respuesta.
  • ErlangReply
Contiene la respuesta en formato de objetos Otp.Erlang.Object.
  • RequestInfo
Contiene el objeto IRequestInfo de la petición que generó esta respuesta.

RequestKind

Es un enumerado que contiene los tipos de peticiones existentes en EVO.

  • Async
Es una petición que no espera por ella misma a que sea completada para retornar el control al programa, tampoco espera por que la respuesta a la misma sea recibida. No retorna información de petición IRequestInfo. La respuesta debe ser obtenida de forma asincrónica a través del evento OnReceive del componente ErlangServerRequest. No es posible abortar esta petición una vez realizada, pero si es posible abortar todas las peticiones del mismo tipo Async incluyéndola, utilizando la función AbortAsyncRequests() del componente ErlangServerRequest.
  • Normal
Es una petición que espera por ella misma a que sea completada para retornar el control al programa, pero no por que sea recibida la respuesta. Es a elección del programador si desea esperar por también por la respuesta para retornar el control al programa, utilizando la función WaitForReply() del mismo objeto IRequestInfo, o abortar la misma utilizando la función AbortRequest() inmediatamente después de realizada la petición. Retorna un objeto IRequestInfo con la información de la petición.
  • ServerSent
Es un tipo de petición que no fue requerida por el cliente, esto significa que puede ser un mensaje global enviado voluntariamente por el servidor ejemplo utilizando la función send_to_all(Descripción, Mensaje) de la plantilla para servidores evo_template. El objeto IRequestInfo del mensaje enviado por el servidor, puede ser obtenido mediante la propiedad RequestInfo del objeto de IServerReply obtenido una vez que el mensaje es recibido a través del evento OnReceive del componente ErlangServerInterface. Este tipo de mensajes puede ser re-direccionado a un manejador de petición ErlangServerRequest utilizando la función SendToErlangServerRequest del mismo componente ErlangServerInterface.

La plantilla evo_template

Archivos de la plantilla para servidores evo_template:

  • 1.install.cmd
Instala la aplicación servidora y su base de datos.
  • 1.start.cmd
Inicia la aplicación servidora.
  • 2.service_install-start.cmd
Instala la aplicación como un servicio de windows.
  • 2.service_stop.cmd
Detiene la ejecución del servicio.
  • 2.service_uninstall.cmd
Desinstala el servicio de windows.
  • compile.cmd
Comando para compilar los códigos fuentes de la carpeta [sources].
  • config.cmd
Archivo de configuración.
  • Carpeta [beam]
Contiene los archivos compilados necesarios para la ejecución de la aplicación servidora.
  • appname.app
Es el fichero de aplicación para las aplicaciones Erlang.
  • appname.beam
Es el punto de entrada a la aplicación servidora.
  • appname_debug_module.beam
Es el módulo de debug para imprimir mensajes en la consola de Erlang.
  • appname_main_interface.beam
Es el módulo de interface principal con el cliente.
  • appname_main_supervisor.beam
Es el módulo de supervisión que vela porque los demás módulos trabajen continuamente. Comportamiento Erlang/Otp.
  • Carpeta [sources]
Contiene los archivos fuentes necesarios para programar una aplicación servidora.
  • appname_db_module.erl
Es el módulo de base de datos, que implementa una capa para la base de datos de Erlang, mnesia. Aquí se pueden escribir los scripts de base de datos.
  • appname_db_server.erl
Es el módulo servidor para las funciones de base de datos, implementa el comportamiento gen_server.
  • appname_request_handler.erl
Módulo de manejo de peticiones de los clientes.
  • to_compile.cmd
Inicia una consola de compilación.
  • user_default.erl
Comandos de la consola de EVO.

Véase también

  • Erlang, Lenguaje de programación funcional de alto nivel.
  • C Sharp, lenguaje de programación orientado a objetos.
  • ejabberd, un servidor de mensajes instantáneos XMPP escrito en Erlang.

Enlaces externos