Monthly Archives: November 2007

Microsoft .NET Remoting

0
Filed under .NET Development

Uno de los temas que hay que preparar para el examen “70-529 – TS: Microsoft .NET Framework 2.0 – Distributed Application Development” es Microsoft .NET Remoting. .NET Remoting es una de las opciones que tenemos para crear aplicaciones distribuidas. Nos permite llamar a objetos que se encuentran en diferentes procesos y en diferentes máquinas como si estuvieran dentro de la misma aplicación. No es recomendable utilizar .NET Remoting cuando la comunicación se va a establecer a través de Internet o la comunicación no es entre plataformas .NET. Un ejemplo de una situación en la que podemos utilizar .NET Remoting puede ser el siguiente:

- Un servicio Windows que puede ser configurado por un administrador y que permite ver el estado de las diferentes funcionalidades que tiene mediante una consola administrativa que es una aplicación de Windows Forms.

En este caso podemos utilizar .NET Remoting con el canal de comunicación IPC (Inter-process communication).

Existen tres tipos de objetos remotos de los cuales dos son de activación servidor y uno de activación cliente. Los objetos de activación servidor los crea el servidor sólo cuando se precisan (cuando el cliente invoca el primer método en el objeto proxy y no cuando utiliza “new” o Activator.GetObject). Dentro de activación servidor tenemos objetos Singleton y objetos SingleCall. Para los objetos Singleton siempre habrá una única instancia para todos los clientes. Para los objetos SingleCall se crea un nuevo objeto por cada invocación que hace el cliente a un método. Cuando el objeto SingleCall no se necesita más, se descarta inmediatamente. Los objetos de activación cliente se crean en el servidor cuando el cliente utiliza “new” o Activator.CreateInstance. El objeto que recibe el cliente es dedicado a pesar que reside en el servidor. Un administrador de tiempo de vida que se basa en arrendamiento administra los objetos para asegurar que los objetos expiren y que no mantengan recursos innecesarios.

Podemos alojar objetos remotos en aplicaciones de consola, Windows Forms, ASP.NET, servicios Windows.

En cuanto a los canales de comunicación .NET Framework 2.0 trae tres que son TCP, HTTP, IPC. Existen algunas reglas que tienen que ver con los canales como por ejemplo tenemos que tener registrado un canal antes de que el propio objeto remoto se registre y cualquiera pueda llamar a sus métodos.

Para que el cliente pueda crear una instancia de un objeto remoto, la aplicación servidor y la aplicación cliente tienen que compartir el mismo ensamblado. Lo que se hace generalmente es crear una biblioteca de clases que contenga interfaces para que sean implementadas por la aplicación servidor y la aplicación cliente. De esta manera la aplicación cliente no está enterada de la implementación que hace la aplicación servidor.

Volviendo al ejemplo anterior, podemos tener un proyecto de tipo biblioteca de clases llamado “AplicacionRemota.Comun” que tenga una interfaz llamada “IEstadoServidor” y que se vea así:

    public interface IEstadoServidor
    {
        int UsuariosConectados { get; }
    }

El proyecto servidor (“AplicacionRemota.Servidor”) que para este ejemplo va a ser una aplicación consola, va a tener una clase llamada EstadoServidor que va a implementar la interfaz IEstadoServidor y va a heredar de la clase MarshalByRefObject:

    public class EstadoServidor : MarshalByRefObject, IEstadoServidor
    {
        #region IEstadoServidor Members

        public int UsuariosConectados
        {
            get
            {
                return new Random().Next();
            }
        }

        #endregion
    }

Notar que tenemos que agregar una referencia al ensamblado “System.Runtime.Remoting” en la aplicación servidor.

Nos queda registrar el canal y el tipo remoto para que pueda aceptar solicitudes desde la aplicación cliente. Una de las formas que tenemos es utilizando las clases ChannelServices y RemotingConfiguration. En el “Main” de la aplicación servidor ponemos lo siguiente:

        static void Main(string[] args)
        {
            IpcServerChannel lIpcServerChannel = new IpcServerChannel("NombreCanal");
            ChannelServices.RegisterChannel(lIpcServerChannel, false);
            RemotingConfiguration.RegisterWellKnownServiceType(typeof(EstadoServidor),
                "URIObjeto", WellKnownObjectMode.Singleton);
            Console.ReadLine();
            ChannelServices.UnregisterChannel(lIpcServerChannel);
        }

El proyecto cliente (“AplicacionRemota.Cliente”) que para este ejemplo también va a ser una aplicación consola, va a tener el siguiente código en el método “Main”:

        static void Main(string[] args)
        {
            IEstadoServidor lIEstadoServidor = (IEstadoServidor)Activator.GetObject
                (typeof(IEstadoServidor), "IPC://NombreCanal/URIObjeto");
            Console.Write(lIEstadoServidor.UsuariosConectados);
            Console.ReadLine();
        }