Introducción

Anuncio
Introducción
En esta nueva práctica vamos a seguir explorarando nuevos “modo de vida”. Ya
hemos visto que este concepto es fundamental para entender el funcionamiento de
una aplicación distribuida.
Curso de Middleware. Práctica 4.
1 de 11
Extendiendo los modos de vida
Hasta el momento hemos vistos dos modelos de vida de los objetos remotos:
SingleCall y Singleton. En ambos casos, el servidor crea el objeto cuando el cliente
realiza una petición. En el caso del SingleCall el servidor elimina el objeto cuando
termina la llamada y en el caso de Singleton el objeto sigue activo durante un tiempo
que puede ser configurable. En este ejemplo vamos a trabajar con nuevos modos de
vida de un objeto.
El modo “SingleCall” es un modo de vida que recuerda mucho la filosofía de HTTP y
de las páginas web. Se abre una conexión, se solicita un recurso y se cierra la
conexión. Al menos en su forma más habitual. Se suele utilizar cuando se requiere un
servicio que no mantiene un estado previo. Por ejemplo, para lanzar una impresión en
un servidor de impresoras.
El modo “Singleton” en cambio se utiliza cuando es necesario mantener un estado en
el servidor y que este estado sea común y único entre todos los clientes. El ejemplo
más representativo es el servidor de nombres que hemos desarrollado durante este
curso.
Pero a veces es necesario mantener un estado y que este estado sea propio de cada
cliente. Un ejemplo de ello se produce en la lista de la compra en los comercios
online. Cada usuario tiene su propia lista de compra y no esperamos que un usuario
vea lo que está comprando otro. En estos casos, los modos de vida anteriores no
suelen ser recomendables. Queremos que sea el programa cliente quien tenga dicha
responsabilidad de crear y mantener el objeto remoto. En ese caso hablamos de
objetos activados por el cliente (Client-Activated Object o CAO).
Antes de entrar en ese concepto vamos a ver cómo se puede configurar Remoting sin
necesidad de ficheros. Para ello vamos a reemplazar el fichero de configuración por
una configuración por código. La configuración por fichero es muy cómoda si la
configuración es conocida de antemano ya que nos evita tener que recompilar el
código. Pero habrá veces que no es posible conocer los parámetros de la configuración
hasta el momento de la ejecución (por ejemplo, si le pedimos al usuario los datos de
conexión). En esos casos, la configuración tendremos que hacerla por programa. El
código del servidor sería algo del estilo:
Curso de Middleware. Práctica 4.
2 de 11
//Servidor.cs
using System;
using System.Runtime.Remoting;
//Atencion a estos using:
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using Calculo;
public class Servidor
{
public static void Main (string[] args)
{
//RemotingConfiguration.Configure("Servidor.config");
HttpChannel chnl = new HttpChannel(1234);
ChannelServices.RegisterChannel(chnl);
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(Calculo.Calculadora),
"Calculadora.remota",
WellKnownObjectMode.Singleton);
Console.WriteLine("Atendiendo las peticiones...");
Console.WriteLine("Pulse Enter para salir...");
Console.ReadLine();
}
}
Si comparamos el fichero de configuración con el código utilizado es evidente la
correspondencia entre uno y el otro. Podemos observar que hemos reemplazado la
llamada a “Configure” por una llamadas a “RegisterChannel” y a
“RegisterWellKnownServiceType “. La primera llamada es necesaria hacerla por cada
uno de los canales que tengamos abiertos en nuestro servidor. La segunda es necesaria
para cada tipo de objeto que queramos publicar. En nuestro ejemplo hemos definido el
objeto como Singleton.
Notad también que hemos incluido los nombres de espacio (namespace)
“System.Runtime.Remoting.Channels” y “System.Runtime.Remoting.Channels.Http“.
Esto es necesario para tener visibilidad sobre las funciones mencionadas.
Dependiendo de la configuración de tu máquina es probable que, para compilar el
ejemplo, tengas que incluir la librería System.Runtime.Remoting.dll en el proceso de
Curso de Middleware. Práctica 4.
3 de 11
compilación.
El cliente también podemos configurarlo mediante programa. Por ejemplo:
//Cliente.cs
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using Calculo;
public class Cliente
{
public static void Main (string[] args)
{
//RemotingConfiguration.Configure("Cliente.config");
HttpChannel chnl = new HttpChannel();
ChannelServices.RegisterChannel(chnl);
RemotingConfiguration.RegisterWellKnownClientType(
typeof(Calculo.Calculadora),
"http://localhost:1234/Calculadora.remota"
);
Console.WriteLine("Creando la calculadora");
Calculadora calc = new Calculadora();
......
Console.WriteLine("Pulse Enter para salir...");
Console.ReadLine();
}
}
Para el cliente podemos hacer los mismos comentarios que hemos hecho para el
servidor. Dejamos al alumno analizar el código y estudiar la correspondencia con el
fichero de configuración.
Curso de Middleware. Práctica 4.
4 de 11
Modo de vida de objeto publicado
Hasta el momento hemos vistos dos modelos de vida de los objetos remotos:
SingleCall y Singleton. En ambos casos, el servidor crea el objeto cuando el cliente
realiza una petición. En el caso del SingleCall el servidor elimina el objeto cuando
termina la llamada y en el caso de Singleton el objeto sigue activo durante un tiempo
que puede ser configurable. En este ejemplo vamos a trabajar con dos nuevos modos
de vida de un objeto.
Hay ocasiones en los que el servidor tiene que crear el objeto antes de cualquier
llamada de los clientes. En este caso, el servidor primero crear los objetos y después
los “publica”. Veamos un ejemplo:
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using Calculo;
public class Servidor
{
public static void Main (string[] args)
{
//RemotingConfiguration.Configure("Servidor.config");
HttpChannel chnl = new HttpChannel(1234);
ChannelServices.RegisterChannel(chnl);
Calculadora calc = new Calculadora();
RemotingServices.Marshal
(calc,"Calculadora.remota");
Console.WriteLine("Atendiendo las peticiones...");
Console.WriteLine("Pulse Enter para salir...");
Console.ReadLine();
}
}
El resto del código, incluyendo el correspondiente al cliente, sigue siendo el mismo.
Curso de Middleware. Práctica 4.
5 de 11
Modo de vida de objeto activado por cliente
Este tipo de objetos se llaman objetos publicados y junto con los objetos de llamada
simple o los singleton forman el grupo de objetos activados por el servidor (ServerActivated Object o también conocidos por SAO). Se llaman de esta forma el hecho de
que cuando un cliente crea un objeto remoto, realmente lo que hace es crear un proxy
al objeto sin comunicarse con el servidor. Únicamente cuando el cliente utiliza alguno
de los servicios del objeto se pone en contacto con el servidor. En ese momento el
servidor decide si crear o reutilizar alguno de los objetos que tiene a tal efecto. Esto
es, la responsabilidad de la vida del objeto recae sobre el servidor.
Cuando queremos que sea el cliente quien tenga dicha responsabilidad hablamos de
objetos activados por el cliente (Client-Activated Object o CAO). Veamos un ejemplo
de como se usan. Primero el servidor:
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using Calculo;
public class Servidor
{
public static void Main (string[] args)
{
HttpChannel chnl = new HttpChannel(1234);
ChannelServices.RegisterChannel(chnl);
RemotingConfiguration.ApplicationName =
"UnServidorDelCurso";
RemotingConfiguration.RegisterActivatedServiceType(
typeof(Calculo.Calculadora));
Console.WriteLine("Atendiendo las peticiones...");
Console.WriteLine("Pulse Enter para salir...");
Console.ReadLine();
}
}
Ahora la configuración del servidor es ligeramente diferente. Lo que publicamos es el
nombre del servidor en lugar del nombre de los recursos que atiende dicho servidor.
En nuestro ejemplo, hemos asignado un nombre de “UnServidorDelCurso”.
Curso de Middleware. Práctica 4.
6 de 11
El código del cliente sería parecido a:
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using Calculo;
public class Cliente
{
public static void Main (string[] args)
{
HttpChannel chnl = new HttpChannel();
ChannelServices.RegisterChannel(chnl);
RemotingConfiguration.RegisterActivatedClientType(
typeof(Calculo.Calculadora),
"http://localhost:1234/UnServidorDelCurso");
Console.WriteLine("Creando muchas calculadoras");
Calculadora calc1 = new Calculadora();
Calculadora calc2 = new Calculadora();
Calculadora calc3 = new Calculadora();
.......
}
}
En este ejemplo, el cliente sigue actuando como de costumbre. Para ver la diferencia
en el comportamiento os proponemos incluir algunas trazas en el cliente con puntos
de parada controladas (con lectura del teclado por ejemplo). Observad la secuencia de
llamadas y de creación de objetos.
Curso de Middleware. Práctica 4.
7 de 11
Ejercicios adicionales
Os proponemos varios ejercicios que nos ayuden a entender el comportamiento de
estas características:
1.- Modifica el código de la calculadora de tal forma que puedas determinar cuantos
objetos se crean y si éstos se comparten entre los clientes. Te recomiendo que te
ayudes de algunas trazas y de variables de instancia. Prueba con los cuatro modos de
vida que hemos visto.
2.- Define en la calculadora un constructor que tome algún valor. La idea es que el
constructor por defecto sin parámetros no sea público. Prueba con los cuatro modos de
vida y comprueba si puedes trabajar con todos ellos.
3.- Prueba a crear varias clases del estilo de la calculadora y modifica el código del
cliente y del servidor para que trabajen con varios objetos de varios tipos de forma
simultanea. La idea de este ejercicio es que compruebes que puedes atender dentro de
un mismo servidor a varios objetos remotos.
4.- Algunos de los ejercicios anteriores podrás hacerlos con una configuración
mediante fichero. Intenta hacerlos usando las dos configuraciones: por fichero y por
programa.
5.- Nos interesa conocer el momento de la liberación del objeto en memoria. Es decir,
queremos conocer el momento en el que el servidor destruye el objeto remoto. En los
lenguajes tipo Java o C# no existen destructores como pueden existir en C++, pero
podemos ayudarnos del patrón “IDisposable”. Busca información sobre el mismo y
aplicarlo a la clase Calculadora. La idea es conocer cuando se libera los objetos. Por
ello, pon una traza en el método “Dispose” correspondiente. Prueba los cuatro modos
de vida. ¿Puedes controlar la muerte y la liberación del objeto remoto en los cuatro
modos de vida?
Es un buen momento para que tu profesor os cuente
conceptos de teoría. No avances en la práctica hasta
asegurarte que has entendido correctamente los objetivos
de la misma!!!!.
Hemos completado nuestra visión de los modos de vida que nos permite .Net
Remoting. El concepto de modo de vida es importante y vamos a seguir
profundizando en algunos puntos de interés:
•
Los objetos remotos están siendo utilizados por hebras (threads)
gestionadas por la capa de comunicaciones. ¿Es importante conocer
este punto? ¿Habría problemas de concurrencia? ¿Por qué? ¿Este
problema aparece en todos los modos de vida?
•
Si nos encontráramos con un problema de concurrencia ¿Cómo lo
evitamos? ¿A nivel del objeto remoto? ¿En el cliente? ¿En ambos?
•
Si volvemos nuestra vista a otros middleware (JavaEE) quizás
podamos razonar sobre los modos de vida que éstos ofrecen. Revisa de
Curso de Middleware. Práctica 4.
8 de 11
nuevo los modos de vida que conoces y compáralos con los que ofrece
JavaEE. ¿Hasta qué punto son similares? Si tienes la oportunidad de
trabajar con Corba, haz el mismo ejercicio.
•
Algunos middleware no soportan todos los modos de vida que
conoces. ¿Cómo haríamos un modo de vida utilizando otro?. La idea
es, por ejemplo, que seamos capaces de simular un sigleton usando
single call. O más interesante aún. ¿Cómo simular un CAO si el
middleware solo nos ofrece SingleCall o Singleton? ¿Podría darse el
caso?
•
A lo largo del curso veremos los WebServices, pero para aquellos de
vosotros que ya conozcáis algo de ellos ¿Qué modo de vida ofrecen?
¿Cómo puedo cambiarlos? ¿Es posible?
Curso de Middleware. Práctica 4.
9 de 11
Resumen
A lo largo de esta práctica hemos aprendido a configurar el middleware por fichero de
configuración y mediante llamadas al sistema. Hemos aprendido dos nuevos modos de
vida, con sus ventajas e inconvenientes. Además hemos visto otros conceptos
relacionados tales como ciclo de vida, concurrencia, etc.
Curso de Middleware. Práctica 4.
10 de 11
Conceptos introducidos
En esta práctica hemos introducido/repasado los siguientes conceptos:
•
Modo Client-Activated Object
•
Modo publicado
•
Ciclo de vida (nacimiento y muerte del objeto)
•
Ventajas e inconvenientes de cada modo de vida
•
Servlets
•
Web Services
•
Concurrencia y áreas sincronizadas en el acceso a los objetos remotos
•
Curso de Middleware. Práctica 4.
11 de 11
Descargar