problema al suscribir un evento en forma remota.....

20/08/2003 - 16:31 por Diego Molina | Informe spam
Hola a todos:
Tengo el siguiente problema, al querer suscribir un evento en forma
remota me aparece el siguiente mensaje:

An unhandled exception of type
'System.Runtime.Serialization.SerializationException' occurred in
mscorlib.dll
Additional information: Cannot find the assembly WinCliente,
Version=1.0.1327.20096, Culture=neutral, PublicKeyToken=null.

A continuación muestro como tengo armado el servidor, el cliente y el objeto
que instancio remotamente, si alguien tiene un poco mas de experiencia en
este tema agradecería su consejo, desde ya muchas gracias

Diego

Cliente
BinaryServerFormatterSinkProvider Provider = new
BinaryServerFormatterSinkProvider();
Provider.TypeFilterLevel System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
BinaryClientFormatterSinkProvider clientProv = new
BinaryClientFormatterSinkProvider();
IDictionary props = new Hashtable();
props["port"] = 0;

TcpChannel chan = new TcpChannel(props, clientProv, Provider);

ChannelServices.RegisterChannel(chan);
HelloServer obj (HelloServer)Activator.GetObject(typeof(RemotingSamples.HelloServer)
,"tcp://localhost:123/SayHello");
if (obj == null)
{
label1.Text="Todo mal";
}
else
{
label1.Text=obj.HelloMethod("Diego");
};
obj.Cambio += new
RemotingSamples.HelloServer.CambioEventHandler(this.message);
///aqui se dispara el mensaje

Objeto
public class HelloServer : MarshalByRefObject
{
public delegate void CambioEventHandler();
public event CambioEventHandler Cambio;

public HelloServer()
{
Console.WriteLine("HelloServer activated");
}

public String HelloMethod(String name)
{
Console.WriteLine("Hello.HelloMethod : {0}", name);
return "Hi there " + name;
}

Servidor
BinaryServerFormatterSinkProvider Provider = new
BinaryServerFormatterSinkProvider();
Provider.TypeFilterLevel System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
BinaryClientFormatterSinkProvider clientProv = new
BinaryClientFormatterSinkProvider();
IDictionary props = new Hashtable();
props["port"] = 123;

TcpChannel chan=new TcpChannel(props, clientProv, Provider);

ChannelServices.RegisterChannel(chan);
RemotingSamples.HelloServer hola = new RemotingSamples.HelloServer();
RemotingConfiguration.RegisterWellKnownServiceType
(hola.GetType(),"SayHello", WellKnownObjectMode.SingleCall);
System.Console.WriteLine("Hit <enter> to exit...");
System.Console.ReadLine();
ChannelServices.UnregisterChannel(chan);
return 0;


DIEGO ANDRES MOLINA
DIPROS S.A.
diego.molina@dipros.com
www.dipros.com
Vicente Gil 582 - Mendoza - Argentina
tel.: 0261-4200051
 

Leer las respuestas

#1 Tristan
21/08/2003 - 12:54 | Informe spam
El paso de delegados entre cliente y servidor no es tan trivial como pudiera
parecer. El problema es que tal como te dice el mensaje de error, el
servidor intenta llamar a un delegado que apunta a un método de un
ensamblado que desconoce.

Para solucionarlo tienes varias opciones:

Establecer el método al que apunta el delegado en un ensamblado común a
cliente y servidor. Personalmente no me parece una gran solución, ya que
cuanto menos código se comparta entre cliente y servidor mejor que mejor,
pero desde luego es la más simple.

Encapsular el delegado en una clase común a cliente y servidor. Es una
solución poco intuitiva y dificil de leer, pero personalmente es la mejor
que he encontrado hasta ahora. Sería algo así:


public class RemoteEvent: MarshalByRefObject
{
private EventHandler target;

private RemoteEvent(EventHandler target)
{
this.target += target;
}

public void Delegado(object sender, EventArgs e)
{
target(sender, e);
}

public static EventHandler Create(EventHandler target)
{
RemoteEvent instancia = new RemoteEvent(target);
return new EventHandler(instancia.Delegado);
}
}

El paso del delegado, sería entonces así:

servidor.Evento += RemoteEvent.Create(new EventHandler(OnEvento));

Donde Evento es un evento del servidor, y OnEvento es un método del cliente.

Este código se puede especializar para cada tipo de delegado, o bien como
hago yo, dejarlo genérico para pasar un EventHandler, y especializar luego
tus propias clases derivadas. De esta forma podrás utilizar una sola clase
para encapsular todos los eventos.

Se que es un tema un poco duro, no se si lo habré conseguido explicar bien,
pero espero que te sirva.


Ahhhh, hay una opción mucho más simple. Olvidarse de pasar delegados y
trabajar directamente con miembros del cliente. Para ello, el servidor tan
solo necesita una referencia al cliente. Los métodos se llamarian entonces
de forma sencilla, tal como lo harias en la dirección contraria. NO es
necesario crear objetos remotos en las dos direcciones. Basta con el del
servidor.

Juan Carlos Badiola
MVP - C#

Preguntas similares