Работа с синглонами в .Net Remoting

У меня возникла проблема с одиночным классом, который я подвергаю удалению через удаленный доступ. На моем сервере у меня есть:

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

RemotableObject - это одноэлементный объект, который наследует MarshalByRefObject.

Мой клиент подключается к нему через:

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

Все работает отлично, поскольку удаленный доступ идет, но когда я обращаюсь к объекту singleton в моем сервере, например:

int someValue = RemotableObject.Instance.SomeDynamicValue;

Он обращается к другому экземпляру, чем клиенты. Я также проверил, что частный конструктор в RemotableObject дважды попадает во время отладки.

Я могу получить желаемое поведение, если я получаю экземпляр RemotableObject через удаленный доступ к моему серверному коду, но есть ли способ, с помощью которого я могу получить доступ к тому же объекту, что и мои клиенты с сервера, без лишних служебных данных?

Ответы

Ответ 1

Если я понимаю, что вам нужно, (вы хотите, чтобы объект жил на сервере, но вы хотите, чтобы все клиентские вызовы получали один и тот же экземпляр объекта на сервере, а также хотите, чтобы вызовы в коде сервера чтобы получить тот же самый экземпляр?)

то, если ваш сервер "ServerName", и он прослушивает порт nnnn, а Uri как "MyMsgEndpointUri", вы определили Uri как:

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

на вашем сервере, инициализируйте конечную точку:

RemotingServices.Marshal([singletonInstance], MesgURI);  

Вместо RegisterWellKnownServiceType();

также, в классе, представляющем singleton, не забудьте переопределить свойство InitializeLifetimeService с нулевой операцией... или объект singleton получит мусор, собранный в какой-то момент...

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

На сервере просто вызовите статический метод factory для oneton-классов, чтобы получить доступ к этому экземпляру singleton... Не используйте удаленные вызовы вообще...

Ответ 2

Я никогда не пытался вызывать Activator.GetObject со стороны сервера, но должен возвращать тот же экземпляр, который используют клиенты. Но вы все равно получите прокси.

Ответ 3

Нет.

Невозможно прочитать память клиента на сервере.