2009-04-09 12 views
14

Estoy teniendo un pequeño problema con una clase de singleton que estoy exponiendo a través de la comunicación remota. En mi servidor tengo:Trabajando con singletons en .Net Remoting

TcpChannel channel = new TcpChannel(Settings.Default.RemotingPort); 
ChannelServices.RegisterChannel(channel, false); 
RemotingConfiguration.RegisterWellKnownServiceType( 
    typeof(RemotableObject), "RemotableObject", 
    WellKnownObjectMode.Singleton); 

RemotableObject es un objeto único que hereda MarshalByRefObject.

Mi cliente se conecta a ella a través de:

remoteObject = (RemotableObject)Activator.GetObject(
    typeof(RemotableObject), 
    string.Format("tcp://{0}:{1}/RemotableObject", serverIP, serverPort)); 

Todo funciona muy bien en cuanto a la interacción remota va, pero cuando accedo al objeto único en mi código de servidor de esta manera:

int someValue = RemotableObject.Instance.SomeDynamicValue; 

Se accede a una instancia diferente a la de los clientes. También he verificado que el constructor privado en RemotableObject recibe dos veces durante la depuración.

Puedo obtener el comportamiento deseado si obtengo una instancia de RemotableObject a través de la comunicación remota en el código de mi servidor, pero ¿hay alguna forma de que pueda acceder al mismo objeto que mis clientes desde el servidor sin la conexión remota?

Respuesta

30

Si entiendo lo que está buscando, (quiere que el objeto viva en el servidor, pero desea que todas las llamadas de los clientes obtengan la misma instancia del objeto en el servidor, y también desea llamadas en el servidor ? código para conseguir que la misma instancia)

continuación, si el servidor es "ServerName", y está escuchando en el puerto nnnn, con Uri como "MyMsgEndpointUri", que ha definido el Uri como:

var MesgUri = "tcp://ServerName:nnnn/MyMsgEndpointUri"; 

en su servidor, Inicialice el punto final por:

RemotingServices.Marshal([singletonInstance], MesgURI); 

En lugar de RegisterWellKnownServiceType();

también, en la clase que representa el singleton, recuerde que debe reemplazar la propiedad InitializeLifetimeService con una operación nula ... o el objeto singleton obtendrá basura recogida en algún momento ...

public override object InitializeLifetimeService() { return (null); } 

Desde el servidor, simplemente llame método de fábrica estática sus clases simples para obtener acceso a esa instancia singleton ... no utilizar la comunicación remota llama a todos ...

+0

¡Eso funcionó perfectamente! ¡Gracias por la rápida respuesta! – Todd

+0

¿Cuál debería ser el valor de 'MesgURI'? Mi canal tcp se llama 'UsersTcp' y lo he intentado con ese nombre y con el uri:' tcp: // localhost: 5000/UserTcp' y ambos me dan un error de "no se encontró servicio". – moondaisy

+0

Debe ser 'tcp: // [ServerName]: [PortNumber]/MesgUri' como en' tcp: // MYSERVERNAME: 5212/UsersTcp' –

-2

No hay manera de leer la memoria del cliente en el servidor.

-1

nunca he intentado llamar Activator.GetObject desde el lado del servidor , pero eso debería devolver la misma instancia que los clientes están utilizando. Pero, aún obtendrás un proxy.