July 6th, 2007Programación con C# y .NET Remoting/Mono Remoting [5/7]
Indice general de los manuales
- Introducción, instalación en Ubuntu y creación de una calculadora.
- Modos de compartición de objetos. Creando nuestra primera calculadora distribuida.
- Modos de compartición de objetos: Singlecall.
- Modos de compartición de objetos: Singleton.
- Modos de compartición de objetos: CAO. « [Leyendo]
- Canales: TCP y HTTP. Configuración en archivo XML.
- Uso de interfaces para separar el código entre cliente y servidor.
CAO
La última de las formas de compartir los objetos desde el servidor es CAO: Client Activated Object. De esta forma, cada cliente que acceda al servidor, podrá crear un objeto en el y usarlo de forma independiente. En nuestro ejemplo, cada cliente tendrá su propia calculadora.

Como vemos, cada cliente tiene su propia calculadora, y cada calculadora guarda su estado.
Aunque el nuevo código del servidor es muy parecido a los anteriores, pongo el cuerpo de Main entero:
- // Archivo: Servidor.cs
- // Descripcion: programa servidor que comparte
- // la clase Calculadora remotamente.
- // Biblioteca estandar y remoting
- using System;
- using System.Runtime.Remoting;
- // Bibliotecas para usar un canal HTTP
- using System.Runtime.Remoting.Channels;
- using System.Runtime.Remoting.Channels.Http;
- using Calculo;
- public class Servidor
- {
- // arg[0] representa el puerto del servidor
- public static void Main (string[] args)
- {
- // Creamos un nuevo objeto para el canal HTTP
- HttpChannel chnl = new HttpChannel(int.Parse(args[0]));
- // Le decimos a la máquina que nos reserve ese canal
- ChannelServices.RegisterChannel(chnl);
-
- // Opciones para la comparticion de la clase
- RemotingConfiguration.ApplicationName =
- “ServidorDeCalculadoras”;
- RemotingConfiguration.RegisterActivatedServiceType(
- typeof(Calculo.Calculadora));
- // Mensajes de espera en la pantalla
- Console.WriteLine(“Atendiendo las peticiones…”);
- Console.WriteLine(“Pulse Enter para salir…”);
- Console.ReadLine();
- }
- }
La configuración del servidor la hemos dividido en dos partes, le hemos adjudicado un nombre que será el del servidor, no el de una calculadora; y después hemos compartido la calculadora.
Vamos a modificar el cliente por completo, para que no tengamos que hacer dos clientes diferentes para ver el funcionamiento de esta forma de compartir.
- // Archivo: Cliente.cs
- // Version: 2.0
- // Descripcion: cliente que usara la clase remota Calculadora
- // Biblioteca estandar y remoting
- using System;
- using System.Runtime.Remoting;
- // Bibliotecas para usar un canal HTTP
- using System.Runtime.Remoting.Channels;
- using System.Runtime.Remoting.Channels.Http;
- using Calculo;
- public class Cliente
- {
- // arg[0] representa el host del servidor
- // arg[1] representa el puerto del servidor
- // arg[2] representa el numero que guardamos en LaBase
- public static void Main (string[] args)
- {
- // Creamos un nuevo objeto para el canal HTTP
- HttpChannel chnl = new HttpChannel();
- // Le decimos a la máquina que nos reserve ese canal
- ChannelServices.RegisterChannel(chnl);
- // Opciones para la utilizacion remota de la clase
- RemotingConfiguration.RegisterActivatedClientType(
- typeof(Calculo.Calculadora),
- “http://” + args[0] + “:” + args[1]);
- // Creamos un objeto
- Calculadora calc = new Calculadora();
- // Practicamos
- calc.LaBase = int.Parse(args[2]);
- Console.WriteLine(“Cambiado a: “ + cacl.LaBase);
- Console.WriteLine(“Pulse Enter para ver el estado…”);
- Console.ReadLine();
- Console.WriteLine(“Hemos cambiado la base a “ + calc.LaBase);
- }
- }
Podemos ver varios cambios en este nuevo cliente:
- A diferencia de los anteriores, solo necesitamos saber el host y el puerto del servidor, no nos hace falta saber el nombre con el que el servidor se ha autodenominado.
- Hemos añadido un nuevo argumento al ejecutar el programa, que será el número que queremos adjudicar a LaBase, y así poder hacer varias pruebas para cambiar el estado desde el cliente sin tener que crear dos.
- Para comprobar que cada cliente tiene su propia calculadora, hemos interrumpido el programa a la mitad (pulsando Enter) para cambiar el estado desde dos clientes diferentes que se ejecutan a la misma vez y comprobar después que cada uno tiene una calculadora con su propio estado.
Ahora solo nos queda compilar los archivos:
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 los archivos en diferentes consolas:
Ejecutar el servidor:
./Servidor.exe 9999
El cliente 1:
./Cliente.exe localhost 9999 5
Y su resultado:
Cambiado a: 5
Pulse Enter para ver el estado…
Y el cliente 2:
./Cliente2.exe localhost 9999 8
Y su resultado:
Cambiado a: 8
Pulse Enter para ver el estado…
Una vez que tenemos los dos clientes cargados, pulsamos Enter en cada uno de ellos y vemos que conservan su estado:
El Cliente 1:
Hemos cambiado la base a 5
El Cliente 2:
Hemos cambiado la base a 8
En el servidor solo veremos como cada cliente crea un nuevo objeto.
Atenciando las peticiones…
Pulse Enter para salir…
Contructor.
Constructor.
Ya que cada cliente puede crearse su propia calculadora, podríamos replantearnos dejar que cada objeto “muera” pasado un tiempo (el tiempo de vida que vimos en el capítulo anterior) o controlar todas las instancias que se hacen desde los servidores con un atributo estático que vaya aumentando por cada instancia. Deberíamos pensar esto ya que puede que alguien malintencionado haga miles de clientes que llamen a nuestro servidor, creando miles de instancias y bloqueando el servidor.
Aunque ya está escrita la parte más importante del manual, en los siguientes capítulos veremos trucos y formas de usar la teoría que hemos dado hasta ahora.
El código fuente de uno de los comentarios expuestos abajo, se encuentra aquí.
Indice general de los manuales
- Introducción, instalación en Ubuntu y creación de una calculadora.
- Modos de compartición de objetos. Creando nuestra primera calculadora distribuida.
- Modos de compartición de objetos: Singlecall.
- Modos de compartición de objetos: Singleton.
- Modos de compartición de objetos: CAO. « [Leyendo]
- Canales: TCP y HTTP. Configuración en archivo XML.
- Uso de interfaces para separar el código entre cliente y servidor.

September 15th, 2007 at 2:33 pm
Hola ! primero de todo felicitarte por el manual, increíble. Súper fácil, paso a paso.. en fin. como tiene que ser !
Lo he seguido hasta aquí y, la verdad, me he quedado con ganas de mas xD
Una pregunta que te quería hacer.. como puedo hacer que el servidor escriba cosas a los clientes.. osea, por ejemplo cuando “alguien” toca LaBase, que el servidor envie a los otros clientes el nuevo valor de LaBase, por ejemplo.
Grácias una vez mas :)
Por cierto, podrías avisarme al mail (javirs@gmail.com) cuando contestes o sigas con el manual ?? es que tengo poco tiempo libre y no se cuando volveré por aquí. Gracias !!!
September 20th, 2007 at 1:25 pm
Hola!
He creado un programa que responde a tu pregunta. Lo puedes ver en la nueva sección de “Source code”, donde estoy poniendo los códigos de todos los tutoriales.
En el código aparecen cosas que aún no he explicado, pero he escrito un montón de comentarios (tantos que casi parece un manual).
Seguiré con los tutoriales y explicaré las cosas que quedan al aire en el código.
La descarga es un proyecto para Visual C# Express 2005, y lo puedes coger aquí.
Saludos.
September 21st, 2007 at 7:36 pm
Gracias jefe
esto promete, al fin alguien hace las cosas con un poco de cariño y pensando en el “inepto medio” (eze zoy yo!)
Si hago cosillas útiles ya te las pasaré para que hagas un spread al universo entero y así ponemos nuestro granito de arena al conocimiento global !!!
October 30th, 2007 at 7:42 pm
Hola, quisiera saber si con el remoting puedo generar una aplicación tipo escritorio remoto (que pueda ejecutarlo en un entorno web).
Gracias
October 30th, 2007 at 9:14 pm
Hola,
Un escritorio remoto si que se puede hacer (yo estuve haciendo uno para hacer pruebas y usarlo en los tutoriales). Lo único que tendría que mirar es como hacerlo web. Me imagino que será con ASP, la cual es una tecnología que tengo pendiente aprender (pues va muy relacionada con C# y .NET/Mono).
Hay un entorno de desarrollo, de esta tecnología, llamado Visual Web Developer. Intentar probarlo y a ver si nos puedes responder tu mismo.
Saludos.
PD. En cuanto trastee con ASP haré alguna prueba de lo que me dices a ver si me sale.
January 3rd, 2008 at 5:49 pm
hola eridem
me gustaria saber si tienes el programa en el haces el escritorio remoto, ya que estoy investigando para hacer uno.
saludos!!
January 3rd, 2008 at 6:07 pm
Hola Jorge,
Te he mandado el código al correo que has puesto en el comentario. Espero que te sirva: para investigarlo o continuarlo.
Saludos.
PD. Incluyeme en los créditos de tu programa, jejeje.
February 20th, 2008 at 8:47 pm
hola eridem, solo me asalta una duda en este tipo de implementación de remoting (CAO), porque la idea de remoting es tener la logica en un servidor y no en los clientes, y según el codigo tú haces un using de la clase Calculo, q es la contenedora de la logica. entonces no me queda muy claro que se cumpla esta premisa. no logro ver en que momento tu haces el enlace para que se trabaje con el objeto remoto.
February 20th, 2008 at 9:04 pm
Hola Julio,
Aunque parezca que estamos usando la librería desde el cliente, en realidad se crea una referencia remota. El using hay que usarlo porque el cliente al menos debe saber que tipo de librería tiene que usar.
Es verdad que al hacer un “new Calculadora()” parece que estamos usando la librería local, pero C# dispone de un mecanismo para crear ciertas clases especiales que pueden redefinir el operador “new”. Creo que lo tengo explicado en alguno de los manuales… Así pues, cuando se hace un “new”, en realidad se crea el objeto hacia la referencia remota y no la local.
Espero que te haya servido la explicación. Puedes probar a escribir trazas en la clase de la calculadora y comprobar que efectivamente aparecen en la consola del servidor y no en la del cliente.
Saludos.
February 21st, 2008 at 1:50 pm
muchas gracias eridem, tienes razón al hacer la traza se nota el tipo de instanciación. otra duda, necesito hacer una aplicacion que via remoting u otro medio, sea capaz de instanciar objetos tipo formulario que estaran en el servidor, en el cliente. mi idea es que el cliente solo posea una pequeña aplicacion lanzadora que sea la que llame a las clases del servidor, y levante desde el servidor los formularios. probé asiendolo con singleton y simplecall, pero al llamar al metodo que muestra el formulario, este se levanta en el servidor no en el cliente. me podrias dar una idea de como resolver esto. de ante mano, muchas gracias.
February 21st, 2008 at 2:03 pm
No sé te he entendido bien. ¿Quieres crear componentes de formulario (como botones) en el servidor e instanciarlos desde el cliente?
Si es así, deberías leerte los siguientes artículos sobre crear interfaces de los objetos para el cliente (para que no posea todo el código).
Luego crearte una clase de un componente de un formulario y hacerla remota. Realmente usando Remoting es como si tuvieras las clases localmente. Mi consejo es que te hagas el programa localmente (es decir, sin remoting) y cuando te funcione, separar las clases para que sean remotas, verás como funciona igual (a lo mejor tienes que tocar 2 o 3 cosas, pero casi na).
Espero que te sirva de ayuda.
February 21st, 2008 at 2:25 pm
es un poco complejo. por ejmplo, tengo una aplicacion que muestra un formulario con un boton que despliega un mensaje. yo quiero que esta aplicacion, osea el archivo ejecutable, esté siempre en el servidor, para facilitar la distribucion de los cambios. en los pc clientes, quiero tener una aplicacion que muestra un menú, tipo árbol, que dependerá del usuario. entonces yo desde el cliente realizaré la invocacion a la clase del formulario remoto, cuando seleccione una de las aplicaciones disponibles del menú. entonces en el cliente solo tendré una pequeña aplicación, y en el servidor estarán todos los multiples ejecutables para las distintas aplicaciones existentes y que se iran desarrollando con el tiempo. mi idea es “emular”, aplicaciones web pero desde winform.
February 23rd, 2008 at 1:18 pm
Creo que ya te he entendido: quieres tener varios ejecutables en el servidor y que el cliente pueda coger cualquiera de ellos y mostrarlos como si los tuviera localmente.
Pues no se me ocurre nada sobre esto. Sería como programar la aplicación en tiempo real en el cliente. La idea de un cliente es que ya sepa todo lo que tiene que hacer y no añadirle “ideas nuevas” según la marcha (en este caso, nuevos formularios).
En cualquier caso, cuando lo termines, me gustaría que me lo pudieras enseñar :)
Saludos.
May 21st, 2008 at 8:41 am
Hola,
estoy buscando algo parecido a lo que has explicado de escitorio remoto. Aún tienes el programa por aquí.
Gracias
Saludos
May 21st, 2008 at 9:53 am
Hola Vicente,
Pues como ya me lo han pedido dos personas, lo voy a poner en la sección de Source Code para quién lo quiera seguir.
Dame un día para colgarlo y pásate mañana.
Saludos.
[Actualización] Ya está listo.
November 11th, 2008 at 11:41 pm
Hola, mi consulta es conrespecto al la programacion en Mono yo se programar en C, C++, y un poquito de C# me gustaria un manual o alguna referencia de algun libro de como empezar a utilizar mono lo estoy corriendo en Ubuntu 8.04 gracias de antemano por la ayuda bye
November 11th, 2008 at 11:54 pm
Hola,
De la misma forma que aprendes .NET Framework aprendes Mono, pues lo que intenta Mono es reproducir las mismas librerías y la misma funcionalidad.
Te recomiendo que uses Monodevelop para programar con Ubuntu, ya que es un buen IDE de programación para C# y Mono. No olvides instalar las librerías de Mono 2 y 3 (.NET 2 y 3 respectivamente):
sudo aptitude install mono-gmcs monodevelop
Te puedo recomendar el libro “Programming C#” de Jesse Liberty, O’Reilly. Y sobre .NET Framework (o Mono), suelo usar la información desde la página de MSDN de Microsoft (aunque esté programando en Mono): http://msdn.microsoft.com/es-es/default.aspx o buscando en foros lo que quiero hacer en el momento.
Saludos.