introducción - cedia

19
Introducción En nuestra segunda práctica vamos a utiliza un middleware llamado .Net Remoting. Este es un entorno (framework) para la construcción de sistemas distribuidos. Como cualquier framework de esta naturaleza, .Net Remoting nos aporta una serie de servicios (incluyendo la creación y gestión del tiempo de vida de los objetos) y mecanismos para el transporte de los mensajes entre objetos que se denominan canales. Nuestra intención con esta práctica es valorar la transparencia que nos ofrece el middleware. En los middleware modernos es habitual ocultar la presencia del mismo y evitar lo máximo posible la modificación de los programas. Veamos un primer ejemplo de un sistema distribuido construido con este middleware. Curso de Middleware. Práctica 2. 1 de 19

Upload: others

Post on 01-Jan-2022

5 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Introducción - CEDIA

IntroducciónEn nuestra segunda práctica vamos a utiliza un middleware llamado .Net Remoting. Este es un entorno (framework) para la construcción de sistemas distribuidos. Como cualquier framework de esta naturaleza, .Net Remoting nos aporta una serie de servicios (incluyendo la creación y gestión del tiempo de vida de los objetos) y mecanismos para el transporte de los mensajes entre objetos que se denominan canales.

Nuestra intención con esta práctica es valorar la transparencia que nos ofrece el middleware. En los middleware modernos es habitual ocultar la presencia del mismo y evitar lo máximo posible la modificación de los programas. Veamos un primer ejemplo de un sistema distribuido construido con este middleware.

Curso de Middleware. Práctica 2. 1 de 19

Page 2: Introducción - CEDIA

Segundo ejemplo: una aplicación distribuidaRetomemos nuestra primera aplicación para convertirla en una aplicación distribuida. Lo que queremos hacer es que nuestro antiguo programa principal actúe de cliente de un servidor que ofrezca servicios de calculadora. Lo que vamos a construir son dos ejecutables (un cliente y otro servidor) que utilizan los servicios de una librería con la calculadora.

Por lo tanto, antes de seguir, vamos a preparar una solución de Visual Studio que tenga tres proyectos. Dos proyectos será de tipo “Aplicación de Consola” y el tercero será una “librería de clases”. La creación del proyecto es muy similar a lo visto en la práctica anterior. Os recomiendo que le pongamos nombres que sean representativos. Por ejemplo, nombremos a los proyectos “Servidor”, “Cliente” y “Calculo”. No detallamos el proceso de creación de estos proyectos. Antes de continuar comprobemos que tenemos algo similar a lo que muestra la siguiente imagen:

Durante la creación automática de los proyectos se habrán creado clases y programas por defecto que podemos renombrar o rehacer para adaptarlos a nuestras necesidades.

El siguiente paso es volver a poner nuestra calculadora en el proyecto que hemos llamado Calculo. Podemos hacer copiar/pegar de la práctica anterior. Pero ahora necesita una pequeña modificación. Tenemos que indicar al sistema que nuestra clase pasa a ser un objeto remoto. Para ello, hacemos heredar la clase de otra llamada “System.MarshalByRefObject”. Por ejemplo:

Curso de Middleware. Práctica 2. 2 de 19

Page 3: Introducción - CEDIA

// Calculadora.cs

using System;

namespace Calculo

{

public class Calculadora : System.MarshalByRefObject

{

... el resto del código ...

}

}

Con esto le estamos indicando al sistema que la clase puede ser “un objeto remoto”. Es decir, que podemos crear una referencia o puntero al objeto remoto, aunque en lugar de almacenar una dirección de memoria habitual, se utilizará información más compleja (máquina, servicio, etc.). Es la forma que tiene el cliente de acceder a la información del objeto almacenada en el servidor.

También necesitaremos un servidor que atienda las peticiones de los clientes y que sea el que realmente cree el objeto de tipo Calculadora. Los clientes harán llamadas a la calculadora, pero esas llamadas serán ejecutadas en el proceso servidor (que incluso podrá estar otra máquina diferente).

En ese programa pondremos un código similar al siguiente:

// Program.cs

using System;

using System.Runtime.Remoting;

namespace Servidor

{

class Program

{

static void Main(string[] args)

{

RemotingConfiguration.Configure("Servidor.exe.config",

false);

Console.WriteLine("Atendiendo las peticiones...");

Console.WriteLine("Pulse Enter para salir...");

Console.ReadLine();

}

}

}

Para que el servidor compile debemos acordarnos que tenemos que incluir el “using” correspondiente a “System.Runtime.Remoting”. También tenemos que incluir la

Curso de Middleware. Práctica 2. 3 de 19

Page 4: Introducción - CEDIA

referencia a la librería “Calculo”. Veamos cómo dar esos dos pasos:

y,

Ahora tenemos que editar el fichero de configuración del servidor. Para ello debemos editar el fichero que aparece en el proyecto llamado “App.config”. Este fichero cambia de nombre cuando VisualStudio compila el proyecto. Le llama según el nombre del ejecutable que tenga el proyecto. En nuestro caso, si todo ha sido correcto, VisualStudio lo renombrará a “Servidor.exe.config”. Podéis comprobarlo si entráis en el directorio “bin/Debug” que existe dentro del directorio de trabajo de vuestro proyecto.

Curso de Middleware. Práctica 2. 4 de 19

Page 5: Introducción - CEDIA

Cuando abramos el fichero “App.config” seguramente veamos algo parecido a:

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

<startup>

<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"

/>

</startup>

</configuration>

En ese fichero ahora debemos insertar los parámetros de configuración de nuestro servidor. Debemos editarlo para que sea similar al siguiente (he marcado en color la parte que debemos añadir):

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

<system.runtime.remoting>

<application>

<service>

<wellknown

mode="SingleCall"

type="Calculo.Calculadora, Calculo"

objectUri="Calculadora.remota"

/>

</service>

<channels>

<channel ref="http" port="1234"/>

</channels>

</application>

</system.runtime.remoting>

<startup>

<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"

/>

</startup>

</configuration>

Como podemos observar el fichero de configuración tiene una estructura típica de XML. El primer nivel le indica que es un fichero de configuración y el segundo (el elemento <system.runtime.remoting>) que la configuración se refiere al sistema de remoting. Vemos también que hay un punto donde indicamos el tipo de protocolo a

Curso de Middleware. Práctica 2. 5 de 19

Page 6: Introducción - CEDIA

utilizar (http) y el puerto (1234) en el que escuchará el servidor.

Es importante que pongas correctamente los nombres de la librería y de tu objeto en la entrada “<wellknown/>” del fichero de configuración. Si tienes algún problema, consulta en la ayuda o en el web de Microsoft (MSN). No vamos a detallar el esquema de estos ficheros de configuración ya que son propios de .Net Remoting y nuestro interés es entender el comportamiento de los Middleware en general.

Por el momento, vamos a compilar y a lanzar el servidor para estar seguros de que todo es correcto. Si todo va bien, tendremos que ver algo parecido a la siguiente pantalla:

Ahora vamos a pasar a desarrollar nuestro cliente. En el fichero “Program.cs” del proyecto “Cliente” debemos incluir un código muy parecido al programa principal que teníamos de nuestra anterior práctica. Simplemente, hemos añadido una línea para la configuración de Remoting. El código debería ser parecido a lo siguiente:

Curso de Middleware. Práctica 2. 6 de 19

Page 7: Introducción - CEDIA

using System;

using System.Runtime.Remoting;

using Calculo;

using System.Threading;

namespace Cliente

{

class Program

{

public static void Main(string[] args)

{

Thread.Sleep(2 * 1000); // Esto es para darle tiempo al

servidor a que arranque

Console.WriteLine("Esto es una prueba de calculadora");

RemotingConfiguration.Configure("Cliente.exe.config", false);

Console.WriteLine("Creando la calculadora");

Calculadora calc = new Calculadora();

Console.WriteLine("Prueba de suma 5+3=" + calc.Suma(5, 3));

Console.WriteLine("Prueba de producto 5*3=" + calc.Producto(5,

3));

Console.WriteLine("Pulse Enter para salir...");

Console.ReadLine();

}

}

}

Al igual que antes, para que nuestro proyecto compile y funcione, tenemos que incluir los “using” correspondientes y la referencia al proyecto “Calculo”. Observad que el fichero de configuración que se carga en la llamada a “Configure” es ahora “ Cliente.exe.config”. De nuevo, debemos editar el fichero “App.config” y confiemos en que VisualStudio cambie el nombre correctamente. Para el cliente, el fichero de configuración debe ser algo de este estilo:

Curso de Middleware. Práctica 2. 7 de 19

Page 8: Introducción - CEDIA

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

<system.runtime.remoting>

<application>

<client>

<wellknown

type="Calculo.Calculadora, Calculo"

url="http://localhost:1234/Calculadora.remota"

/>

</client>

</application>

</system.runtime.remoting>

<startup>

<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"

/>

</startup>

</configuration>

Para probar nuestro ejemplo ahora tenemos que arrancar tanto el servidor como el cliente. Tenemos dos formas de hacer esto. Una es entrar en los directorios “bin/Debug” de cada proyecto y lanzar desde dos consolas diferentes (y por lo tanto desde fuera de VisualStudio) los ejecutables “Servidor.exe” y “Cliente.exe”.

Si queremos hacerlo desde VisualStudio debemos entrar en las propiedades de la solución y seleccionar arranque de múltiples proyectos. Deberíamos ver una pantalla similar a la siguiente:

En estos momentos ya estamos en disposición de arrancar nuestros ejecutables y comprobar si el funcionamiento es el esperado. Si todo es correcto, deberíamos

Curso de Middleware. Práctica 2. 8 de 19

Page 9: Introducción - CEDIA

observar la siguiente pantalla:

Pulsando “enter” en ambas pantallas cerramos las mismas y terminamos la ejecución.

Aparentemente no parece que hayamos hecho nada diferente a nuestra práctica anterior, pero vamos a retomar nuestras antiguas trazas para comprobar si las operaciones matemáticas de la calculadora se ejecutan en el cliente o en el servidor. Se admiten apuestas!!

Después de incluir trazas en lo métodos de sumar y producto, podremos observar dónde aparecen las trazas. Si todo es correcto, éstas aparecerán en la pantalla del servidor y tenemos que ver algo similar a lo siguiente,

Curso de Middleware. Práctica 2. 9 de 19

Page 10: Introducción - CEDIA

Hemos construido nuestra primera aplicación distribuida!!. No ha sido tan difícil verdad? Y lo hemos conseguido en apenas unos minutos y con muy pocas líneas de código. De hecho, las únicas líneas adicionales sobre nuestra práctica anterior son las dos líneas de configuración “RemotingConfiguration.Configure(...);”.

Esa es la magia de un middleware!

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 construido una aplicación cliente/servidor en apenas unos minutos, pero empiezan a aparecer muchos conceptos nuevos que debemos meditar. Por favor, intenta explicar los siguientes puntos:

• Entiendes el concepto de Middleware como plataforma para desarrollar aplicaciones distribuidas. Entiendes que .Net Remoting es un middleware. Algunos autores consideran que un middleware debe facilitar otros servicios tales como movilidad, transaccionalidad, seguridad, etc. En ese sentido, .Net Remoting no se podría considerar un middleware como tal. ¿O si?

• Antes de seguir piensa que alternativas tenemos para desarrollar un ejemplo similar. ¿Cómo lo harías sin un middleware?. ¿Habrías utilizado más líneas de código? Tienes alternativas en RMI, Corba y otros. Si sabes algo de estos sistemas, intenta compararlos con .Net Remoting a lo largo de las prácticas y de nuestras preguntas.

• ¿Puedes decir cómo se identifican los objetos “Calculadora” remotos?. ¿sabes qué es una URL? ¿Se te ocurre alguna alternativa?. ¿Sabes lo qué es una UUID?. ¿Podrías decir alguna ventaja o inconveniente de los métodos propuestos?. La identificación de objetos o servicios remotos es importante. ¿Cómo lo hacen otros middleware?

• El cliente apenas ha sufrido cambios, pero ahora ejecuta una calculadora remota. Puedes descubrir la forma que tiene el sistema de conectar dos conceptos diferentes: por un lado el objeto creado con “new Calculadora()” y por otro el objeto remoto que se ejecuta en el servidor.

• La calculadora parece que tiene ahora dos nombres: “Calculo.Calculadora” y “Calculadora.remota”. ¿Sabes distinguirlos? ¿Puedes explicar ambos nombres? ¿Es necesario tener dos nombres diferentes?. ¿Cómo los relaciona el sistema?

• La librería “Calculo.dll” debe ser compartida entre el cliente y el servidor. Asegúrate. ¿Es necesario?. Este punto es importante y nos abre la puerta a nuevas prácticas.

Curso de Middleware. Práctica 2. 10 de 19

Page 11: Introducción - CEDIA

• Hemos utilizado una arquitectura cliente/servidor muy sencilla, pero ¿puedes explicar la diferencia entre arquitecturas P2P y cliente/servidor?. ¿Necesitamos un middleware diferente?

Curso de Middleware. Práctica 2. 11 de 19

Page 12: Introducción - CEDIA

Ejercicios adicionales

Sobre el código anterior, vamos a realizar algunos cambios que nos ayuden a comprender otros conceptos relevantes. El objetivo de los mismos es demostrar que el middleware nos hará transparente muchos de los conceptos habituales de la programación. Vamos a por ellos:

1. Completa la calculadora con otras funciones que utilicen algunos de los tipos básicos: strings, byte, char, short, int, long double, etc. Tanto con signo como sin él (por ejemplo, int vs uint, short vs ushort, etc). Haz algunas pruebas. Podrás comprobar que el sistema es transparente. Únicamente tendrás que cambiar la clase calculadora y el programa cliente que lo realiza las pruebas.

Este ejercicio nos demuestra que el sistema puede enviar por la red tipos básicos (veremos que este concepto se llama serializar) y que lo hace de forma completamente transparente al programador. El programador no se tiene que preocupar de la arquitectura o de la representación de los datos (little o big endian) de los mismos.

2. Nuestra calculadora utiliza double pero en las llamadas de prueba hemos utilizado enteros. Observa el comportamiento de la conversión entre tipos (casting). Para ello define otras funciones que utilicen enteros o llama a las funciones con una combinación de enteros y doubles. Por ejemplo:

Console.WriteLine("Division 11/2=" + calc.Divide(11,2));

Console.WriteLine("Division 11/2=" + calc.Divide(11.0,2));

Console.WriteLine("Division 11/2=" + calc.Divide(11,2.0));

Console.WriteLine("Division 11/2=" + calc.Divide(11.0,2.0));

Observa como la conversión de tipos es también transparente al programador. El middleware se ha integrado de tal forma en el lenguaje que es difícil saber si esa conversión la está haciendo el lenguaje o el middleware. ¿verdad?

3. Vamos a probar a hacer sobrecarga (overload) en algún método y prueba a llamar a esos métodos. Por ejemplo, podemos añadir algo de este estilo:

Curso de Middleware. Práctica 2. 12 de 19

Page 13: Introducción - CEDIA

public double Suma(double izq, double dch)

{

Console.WriteLine("Estoy en la suma de doubles, sumando {0} +

{1}", izq, dch);

return izq + dch;

}

public int Suma(int izq, int dch)

{

Console.WriteLine("Estoy en la suma de enteros, sumando {0} +

{1}", izq, dch);

return izq + dch;

}

El middleware vuelve a ayudarnos en esta funcionalidad. La llamada a métodos sobrecargados suele ser responsabilidad del compilador, pero ¿Quién ha realizado esa labor cuando los métodos son remotos?

4. Introduce una función de dividir que detecte si el divisor es cero, en cuyo caso levanta una exception estándar pero con un mensaje propio. Algo del estilo:

if (divisor == 0)

throw new Exception("Dividiendo por cero");

Antes de ejecutar este ejercicio, os pido una pequeña reflexión ¿Dónde saltará la excepción? ¿En el servidor o en el cliente?. Tened en cuenta que nuestro código de calculadora se está ejecutando en el servidor (hemos comprobado ese hecho cuando pusimos trazas). Además, en el servidor no hemos puesto ninguna sentencia de “try {} catch()”. Por lo tanto, ¿Dónde podríamos esperar que salga un mensaje de excepción? ¿Se enterará el cliente? O simplemente, ¿el cliente detectará que el servidor ha fallado?

Ante de seguir leyendo, prueba el funcionamiento....

No sigas si no lo has probado ….

¿Seguro que lo has probado? ….

Si todo ha ido correctamente habrás observado que el servidor no ha generado ninguna traza especial. Ha sido el cliente quién ha detectado la excepción levantada en el código de la calculadora. Lo que nos demuestra este ejemplo es que las excepciones se atrapan automáticamente por el middleware y las transmite de forma transparente hacia el cliente. De nuevo, la magia del middleware hace que el programador no tenga que preocuparse de esas cuestiones.

5. En C# existe una cierta variedad para el paso de parámetros. Podemos definir parámetros de entrada (lo que hemos hecho hasta la fecha), de salida (se indican con “out”) o de entrada-salida (indicados por “ref”). Vamos a comprobar su funcionamiento en el middleware. Añade varios métodos que nos permitan jugar con esa modalidad de parámetros. Por ejemplo,

Curso de Middleware. Práctica 2. 13 de 19

Page 14: Introducción - CEDIA

public double Suma2(double izq, double dch, out double rst)

{

rst = izq + dch;

return rst;

}

public double Suma3(double izq, double dch, ref double rst)

{

rst = izq + dch;

return rst;

}

Ahora os propongo que hagáis algunas llamadas desde el cliente y que comprobemos que el funcionamiento sigue siendo el esperado. ¿Es cierto? ¿Sigue funcionando según el comportamiento habitual?.

Lo importante de este ejercicio es que volvemos a comprobar que el middleware se ha responsabilizado del envío y de la recepción de los datos. Tiene conocimiento sobre el correcto tratamiento de los argumentos.

6. Prueba otras características del lenguaje y observa si el middleware sabe cómo tratar cada caso. Por ejemplo, prueba a utilizar propiedades (get y set), sobreerscritura de métodos (es diferente de la sobrecarga), etc. En algunos de estos casos, el middleware debería ser transparente para el programador (pronto veremos que nos aguardan alguna que otra sorpresa).

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!!!!.

Seguimos comprobando que el middleware nos ofrece una visión muy transparente de la programación habitual. Repasemos algunos conceptos:

• El de parámetros por valor y por referencia son conceptos habituales de la programación. ¿Sabrías decir cómo funciona C# y Java? ¿Son similares? ¿Ha cambiado algo al pasar al modelo distribuido? ¿Las pruebas que hemos realizado son suficientes?

• ¿La representación de los datos en C# o Java viene dada por la máquina virtual? El comportamiento de C# es diferente al de Java. Intenta averiguar si tu sistema es big o little endian. ¿Cómo lo haces? ¿Entiendes la diferencia?

• ¿Conoces la diferencia entre sobrecarga y sobreescritura? En C# (y Java) en el primer caso es el compilador quién resuelve la llamada. En el otro es el interprete de la máquina virtual. ¿Conoces ese

Curso de Middleware. Práctica 2. 14 de 19

Page 15: Introducción - CEDIA

funcionamiento? ¿Sabrías explicar todas las implicaciones que tiene? ¿Sabes qué es la covariance?

• C# dispone de otras características interesantes. Por ejemplo, tiene datos nulos (se expresan poniendo una interrogación al final del tipo, por ejemplo int?), tipos dinámicos (dynamic) o de tipado variable (var). ¿Sabrías explicar qué significan? ¿Podrían influir en el desarrollo de un middleware? ¿Qué sucede con .Net Remoting?

• C# y Java tienen clases genéricas (templates en otros lenguajes). ¿Sería posible hacer un middleware que soporte esas características del lenguaje? Aún no hemos visto algunos conceptos relacionados, pero intenta razonar sobre qué dificultades podrían presentarse.

• En C# existen otros conceptos interesantes tales como eventos y delegados (son referencias a métodos). ¿Los conoces? ¿Sabrías cómo usarlos? ¿Tienen impacto en el middleware? ¿Podrías razonar sobre ello?

• Por último, C# ( y en cierta forma Java) tienen herramientas para trabajar con concurrencia (threads, task, futures, async, await, etc.). En prácticas futuras trabajaremos estos conceptos, pero es interesante que nos preparemos y aprendamos algo de ellos. ¿Sabes lo que es una hebra? ¿Sabes qué es un lock (área sincronizada)? ¿Sabrías explicar la razón de que lock en C# tenga un parámetro (normalmente “this”)?

Curso de Middleware. Práctica 2. 15 de 19

Page 16: Introducción - CEDIA

Desarrollando aplicaciones distribuidas. Cuando desarrollamos una aplicación distribuida utilizando conceptos propios de orientación a objetos, como ha sido nuestro caso, nos encontramos con problemas nuevos o que no suelen ser relevante en aplicaciones no distribuidas. Emmerich en su libro “Engineering distributed objects”, publicado por John Wiley & Sons Ltd. menciona los siguientes aspectos:

1. Ciclo de vida o “Life cycle” y Modo de vida: Son conceptos diferentes y no debemos confundirlos. Estos conceptos están relacionados con la creación y destrucción (borrado) de los objetos y hemos visto que se comportan de forma diferente a los objetos normales. Un ejemplo lo hemos visto en nuestra práctica. Además aparecen conceptos nuevos como la migración entre servidores de los mismos. Cuando desarrollemos una aplicación distribuida debemos pensar qué modo de vida tienen nuestros objetos y qué ciclo de vida tienen. Cada objeto en nuestra aplicación distribuida deberá tener un modo de vida que cumpla con las funcionalidad esperada y que además tenga en cuenta conceptos de rendimiento, seguridad, etc.. Debemos conocer los modos de vida más habituales y poder razonar sobre ellos. Veremos mucho más a tal respecto en las prácticas sucesivas.

2. Nombrado y localización: Los objetos locales tienen asociado un nombre que el sistema resuelve internamente mediante un puntero de memoria o referencia. Este mecanismo no es válido cuando tenemos aplicaciones remotas. Los punteros a memoria o referencias deben ser sustituidos por otras soluciones más complejas. Además aparecen problemas adicionales. El trabajo del compilador que transforma un nombre en un puntero, ahora se ve convertido en un servicio de nombrado. Un caso similar sucede cuando transformamos www.unaurl.es en una ip concreta mediante un DNS. Es decir, cuando tenemos aplicaciones distribuidas solemos necesitar servidores de nombrado. Todo esto nos abre de nuevo un mar de posibilidades y políticas de servicios que tendremos que estudiar antes de hacer una aplicación distribuida profesional. Debemos aprender los mecanismos que nos ofrece nuestro middleware, entender sus limitaciones y estudiar la forma de adaptarlo a nuestras necesidades.

3. Latencia: La latencia es el tiempo que tarda en ejecutarse nuestra llamada, medida desde el punto de vista de nuestro cliente. Evidentemente una llamada remota es más lenta que una llamada local. Por un lado, necesitamos un tiempo para localizar y conectar con el servidor y por otro, tenemos que transmitir los parámetros de la llamada. Debemos elegir una arquitectura que sea óptima en este sentido. Si podemos, debemos reducir las llamadas a objetos remotos. O hacer que éstas tengan poca latencia. O hacer llamadas a métodos asíncronos. Normalmente, los middleware modernos nos ofrecen esa capacidad.

4. Activación de los objetos: Cuando en una aplicación local utilizamos objetos o variables, asumimos que éstos siempre están presentes. ¿Os imagináis un escenario en el que estáis utilizando una variable que aparece o desaparece sin sentido?. Esto puede pasar con objetos remotos. Los objetos “viven”en servidores que pueden caer y rearrancar. Esto nos implica preparar nuestra aplicación distribuida para tales casos, y si es posible, nuestro middleware debería hacer transparente estos problemas. Pero en cualquier caso, debemos

Curso de Middleware. Práctica 2. 16 de 19

Page 17: Introducción - CEDIA

estar preparados y conocer los mecanismos que nos ofrece el sistema para evitar o minimizar los problemas.

5. Concurrencia: Los objetos remotos son esencialmente concurrentes. Los servidores atiende las peticiones de varios clientes, por lo que sin la protección adecuada, pueden surgir problemas habituales de los sistemas concurrentes.

6. Comunicación: La comunicación entre procesos implica muchos elementos tales como mecanismos de comunicación (tcp, udp, ..), protocolos (http, ioop, ..) y formato de los mensajes (serialización de los datos). Es importante conocer todo el proceso para poder decidir.

7. Seguridad: La seguridad de las comunicaciones, identificación de los clientes y otros problemas similares son relevantes en una aplicación distribuida. Aunque en nuestras curso apenas trabajamos sobre estos conceptos, no por ello dejan de ser importantes.

8. Tolerancia a Fallo: En el proceso de llamada a objetos remotos hay muchos más puntos de fallo que en una aplicación local: comunicaciones, activación de los objetos, etc.

Además de todos estos problemas, nos gustaría mencionar otros problemas:9. Versionado. Por versionado entendemos los problemas que surgen cuando

una aplicación llama a objetos de una versión diferente. Es un problema que puede aparecer cuando nuestros objetos tienen nuevas funciones o parámetros. Si el cliente no es consciente de tales cambios, el proceso de llamada puede fallar en el mejor de los casos o producir un resultado incoherente que no es fácil de detectar en los casos más graves. En una aplicación local este problema no suele ser importante ya que el compilador se asegura de que programa utiliza la misma versión de los objetos, llegando a recompilar todos los fuentes si detecta un problema.

10. Distribución de ejecutables. Este es un problema asociado tanto a la migración de los objetos como al versionado. Cuando una aplicación detecta la necesidad de migrar un objeto de un servidor a otro, el problema no se limita a transferir el estado del mismo. A veces, es necesario transferir también el código ejecutable del objeto. Esto es, debemos pensar en cómo se transfiere la librería que contiene el código del objeto. Una vez transferido el código, el siguiente punto a considerar sería el proceso de carga de la librería en el ejecutable (p.e ¿sustituye a la que ya tuviera?).

Curso de Middleware. Práctica 2. 17 de 19

Page 18: Introducción - CEDIA

ResumenA lo largo de esta práctica hemos aprendido a construir nuestra primera aplicación distribuida. Hemos visto en funcionamiento un middleware y empezamos a entender qué podemos esperar de él. Este primer ejemplo nos ha permitido repasar conceptos de programación y cómo el middleware los ha tratado.

Curso de Middleware. Práctica 2. 18 de 19

Page 19: Introducción - CEDIA

Conceptos introducidosEn esta práctica hemos introducido/repasado los siguientes conceptos:

• Aplicación distribuida• Concepto de Middleware• Utilización de URL versus UUID• Plataformas Peer-to-Peer versus cliente/servidor• Nombrado de objetos remotos• Tipos de datos dinámicos, variables y nullables• Sobrecarga y sobreescritura• Eventos y delegados• Excepciones,• Threads, locks• Paso de parámetros out y ref• Representación de datos big endian y little endian.

Curso de Middleware. Práctica 2. 19 de 19