Indice general de los manuales

  1. Introducción, instalación en Ubuntu y creación de una calculadora.
  2. Modos de compartición de objetos. Creando nuestra primera calculadora distribuida.
    1. Modos de compartición de objetos: Singlecall.  «  [Leyendo]
    2. Modos de compartición de objetos: Singleton.
    3. Modos de compartición de objetos: CAO.
  3. Canales: TCP y HTTP. Configuración en archivo XML.
  4. Uso de interfaces para separar el código entre cliente y servidor.

SingleCall

El código fuente de este tutorial te lo puedes bajar desde aquí.

Como se explicó en el anterior capítulo, SingleCall es una de las posibles formas en la que el servidor comparte una clase. De esta forma, los clientes podrán hacer instancias a los métodos de una clase remota sin guardar el estado. Esto es así ya que una vez que al servidor se le hace la petición de invocar ese método, éste crea una instancia del objeto de esa clase, ejecuta el método, y vuelve a destruir el objeto creado.

singlecall

Como podemos ver en el ejemplo, los objetos se crean y se destruyen una vez que el cliente ha obtenido una respuesta del método que ha llamado.

Por fin, vamos a pasar a la acción y a crear un cliente y un servidor. El servidor usará la forma de compartir SingleCall, y sacaremos algunas conclusiones de la ejecución:

El código del servidor será:

  1. // Archivo: Servidor.cs
  2. // Descripcion: programa servidor que comparte
  3. // la clase Calculadora remotamente.
  4.  
  5. // Biblioteca estandar y remoting
  6. using System;
  7. using System.Runtime.Remoting;
  8.  
  9. // Bibliotecas para usar un canal HTTP
  10. using System.Runtime.Remoting.Channels;
  11. using System.Runtime.Remoting.Channels.Http;
  12. using Calculo;
  13.  
  14. public class Servidor
  15. {
  16.   // arg[0] representa el puerto del servidor
  17.   public static void Main (string[] args)
  18.   {
  19.     // Creamos un nuevo objeto para el canal HTTP
  20.     HttpChannel chnl = new HttpChannel(int.Parse(args[0]));
  21.  
  22.     // Le decimos a la máquina que nos reserve ese canal
  23.     ChannelServices.RegisterChannel(chnl);
  24.  
  25.     // Opciones para la comparticion de la clase
  26.     RemotingConfiguration.RegisterWellKnownServiceType(
  27.       typeof(Calculo.Calculadora),
  28.       “Calculadora.remota”,
  29.       WellKnownObjectMode.SingleCall);
  30.  
  31.     // Mensajes de espera en la pantalla
  32.     Console.WriteLine(“Atendiendo las peticiones…”);
  33.     Console.WriteLine(“Pulse Enter para salir…”);
  34.     Console.ReadLine();
  35.   }
  36. }

Como podemos ver, el código del servidor es realmente simple. Creamos un canal por el que vamos a escuchar cuando nos hagan peticiones para usar la clase. La única parte que no hemos comentado en el código es las opciones de la compartición. Para compartir una clase, primero deberemos decir que clase queremos compartir, así pues, recogemos la clase Calculadora que tenemos en el espacio de nombres Calculo “typeof(Calculo.Calculadora)”. Después asignamos un nombre con el que los clientes deben referirse a nuestra clase (como veremos en el código del cliente), que hemos llamado “Calculadora.remota”, pero que puede ser otro cualquiera. Y la parte más importante es la forma en la que compartimos la clase: “SingleCall”. Una vez que el servidor está compartiendo la clase, “pararemos” el programa con la espera de una lectura por teclado.

El código del cliente es igual de simple y parecido:

  1. // Archivo: Cliente.cs
  2. // Descripcion: cliente que usara la clase remota Calculadora
  3.  
  4. // Biblioteca estandar y remoting
  5. using System;
  6. using System.Runtime.Remoting;
  7.  
  8. // Bibliotecas para usar un canal HTTP
  9. using System.Runtime.Remoting.Channels;
  10. using System.Runtime.Remoting.Channels.Http;
  11. using Calculo;
  12.  
  13. public class Cliente
  14. {
  15.   // arg[0] representa el host del servidor
  16.   // arg[1] representa el puerto del servidor
  17.   public static void Main (string[] args)
  18.   {
  19.     // Creamos un nuevo objeto para el canal HTTP
  20.     HttpChannel chnl = new HttpChannel();
  21.  
  22.     // Le decimos a la máquina que nos reserve ese canal
  23.     ChannelServices.RegisterChannel(chnl);
  24.  
  25.     // Opciones para la utilizacion remota de la clase
  26.     RemotingConfiguration.RegisterWellKnownClientType(
  27.       typeof(Calculo.Calculadora),
  28.       “http://” + args[0] + “:” + args[1] + “/Calculadora.remota”);
  29.  
  30.     // Ahora, usamos la calculadora como si la clase
  31.     // la tuvieramos en nuestro ordenador
  32.     Calculadora calc = new Calculadora();
  33.     Console.WriteLine(“Suma 2+2 = “ + calc.Suma(2.0, 2.0));
  34.     Console.WriteLine(“Potencia 10^5 = “ + calc.Potencia(5.0));
  35.  
  36.     // Vamos a comprobar como no se guarda el estado
  37.     calc.LaBase = 5.0;
  38.     Console.WriteLine(“Hemos cambiado la base a 5.0″);
  39.     Console.WriteLine(“Pero la base es: “ + calc.LaBase);
  40.  
  41.     try
  42.     {
  43.       Console.WriteLine(“Division 8/2 = “ + calc.Divide(8.0,2.0));
  44.       Console.WriteLine(“Division 5/0 = “ + calc.Divide(5.0,0.0));
  45.     }
  46.     catch (Exception e)
  47.     {
  48.       Console.WriteLine(e);
  49.     }
  50.   }
  51. }

El cliente, al igual que el servidor, necesita registrar el canal por el cual va a hacer las peticiones. Después necesitará recoger el tipo de la clase que se comparte remotamente, y también deberá indicar la dirección en la que se proporciona el servicio. Como vemos, al cliente no hay que especificarle que el servidor está compartiendo su clase de forma SingleCall.

Ahora compilaremos los tres archivos para hacer las pruebas:

mcs -target:library Calculo.cs
mcs -r:Calculo.dll -r:System.Runtime.Remoting.dll Servidor.cs
mcs -r:Calculo.dll -r:System.Runtime.Remoting.dll Cliente.cs

Ejecutaremos en una consola el servidor:

./Servidor.exe 9999

Y en otra consola el cliente:

./Cliente.exe localhost 9999

Observamos el resultado del servidor:

Atendiendo las peticiones…
Pulse Enter para salir…
Constructor.
Metodo: Suma.
Constructor.
Metodo: Potencia.
Constructor.
Constructor.
Constructor.
Metodo: Divide.
Constructor.
Metodo: Divide.

Al meter una traza en el constructor de la calculadora, podemos observar que cada vez que hacemos una llamada a un método, se llama al constructor, es decir, el servidor crea una nueva instancia de la calculadora.

Y ahora la salida del cliente:

Suma 2+2 = 4
Potencia 10^5 = 100000
Hemos cambiado la base a 5.0
Pero la base es: 10
Division 8/2 = 4
System.Exception: Division por 0

Podemos ver dos cosas interesantes:

  1. Como recordaremos, el atributo laBase se inicializa a 10 cada vez que se llama al constructor de la calculadora. Aunque en una instrucción hayamos cambiado LaBase a 5.0, al volverla a recoger en una instrucción posterior, será 10. Podemos observar que el objeto no ha guardado el estado, o mejor dicho, en realidad eran dos instancias de la clase calculadora.
  2. La segunda cosa interesante que podemos ver es que las excepciones las recoge el cliente, así el servidor será seguro y no se interrumpirá.

Todavía nos quedan muchas cosas por ver: elegir un canal TCP en lugar de HTTP, controlar la vida de los objetos, como compilar el cliente sin la clase implementada Calculadora, etc. Aunque lo dejamos aquí para que podáis ir probando y contándome vuestras dudas.

Indice general de los manuales

  1. Introducción, instalación en Ubuntu y creación de una calculadora.
  2. Modos de compartición de objetos. Creando nuestra primera calculadora distribuida.
    1. Modos de compartición de objetos: Singlecall.  «  [Leyendo]
    2. Modos de compartición de objetos: Singleton.
    3. Modos de compartición de objetos: CAO.
  3. Canales: TCP y HTTP. Configuración en archivo XML.
  4. Uso de interfaces para separar el código entre cliente y servidor.

Indice general de los manuales

  1. Introducción, instalación en Ubuntu y creación de una calculadora.
  2. Modos de compartición de objetos. Creando nuestra primera calculadora distribuida.  «  [Leyendo]
    1. Modos de compartición de objetos: Singlecall.
    2. Modos de compartición de objetos: Singleton.
    3. Modos de compartición de objetos: CAO.
  3. Canales: TCP y HTTP. Configuración en archivo XML.
  4. Uso de interfaces para separar el código entre cliente y servidor.

Introducción

El objetivo de esta lección es conocer la forma en la que un servidor puede compartir su calculadora y también modificar ligeramente nuestra calculadora para que sea una clase referenciada remotamente. No es objetivo aprenderse estos conceptos de memoria ni comprenderlos completamente, ya que en las siguientes lecciones haremos un programa por cada una de estas formas.

El código fuente de este tutorial te lo puedes bajar desde aquí.

1. Formas de compartir nuestra calculadora

Hay varias formas de compartir remotamente una clase desde un servidor.

  • SingleCall: Los clientes solo podrán hacer una invocación al método de una clase y obtener una respuesta, pero el objeto del servidor no podrá guardar el estado, ya que el servidor creará un nuevo objeto por petición del cliente, efectuará la operación solicitada y destruirá la instanciación de ese objeto.

    singlecall

    En el ejemplo ilustramos como después de la primera llamada (estrella 1), el servidor crea un objeto de la calculadora, hace la petición de la suma, después le devuelve el resultado al cliente y a continuación borra el objeto del servidor. La segunda llamada (estrella 2) que hace el cliente a la calculadora, el servidor crear el objeto y hasta que no le responda al cliente, el objeto no lo borrará. Podemos comprobar como nos sería imposible guardar el estado de un objeto, ya que el servidor borra el objeto al dar una respuesta al cliente.

  • Singleton: Con este modo, todos los clientes comparten un mismo objeto en el servidor. De este modo, el servidor si que guarda una única instancia del objeto y así será posible guardar su estado.

    singleton

    Al contrario que en SingleCall, esta vez podemos cambiar el estado del objeto del servidor, ya que no se destruirá en ningún momento, y además podrán compartir el mismo objeto varios clientes.

  • Objetos activados en el cliente: Son iguales a los SingleCall pero con la diferencia de que los objetos guardan el estado en el servidor, es decir, el servidor guarda todos los objetos de los clientes.

    cao

    Como podemos ver, cada cliente tiene su propio objeto en el servidor y cada uno conserva su propio estado.

2. Hacer que nuestra clase sea remota

Para que una clase se pueda compartir de forma remota, únicamente hará falta añadir la interfaz System.MarshalByRefObject a esa clase. Este nombre es muy intuitivo, significa que la clase se puede serializar (aplanar) por una referencia remota. Con referencia remota, queremos decir que en lugar de almacenar el objeto en memoria, se guardarán datos como la dirección, el puerto y otros para poder llegar hasta ese objeto que está en otra máquina. Así, si tenemos una referencia a esta clase, podremos usar sus servicios. Añadiendo esta interfaz, el código de nuestra calculadora debería quedar de la siguiente forma:

  1. // el código del anterior tutorial…
  2. public class Calculadora: MarshalByRefObject
  3. {
  4.   // el código del anterior tutorial…
  5. }
  6. // el código del anterior tutorial…

Indice general de los manuales

  1. Introducción, instalación en Ubuntu y creación de una calculadora.
  2. Modos de compartición de objetos. Creando nuestra primera calculadora distribuida.  «  [Leyendo]
    1. Modos de compartición de objetos: Singlecall.
    2. Modos de compartición de objetos: Singleton.
    3. Modos de compartición de objetos: CAO.
  3. Canales: TCP y HTTP. Configuración en archivo XML.
  4. Uso de interfaces para separar el código entre cliente y servidor.

© 2007 El blog de ERiDeM. Free wordpress themes.