Работа с синглетами в .Net Remoting - PullRequest
14 голосов
/ 10 апреля 2009

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

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 ) );

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

int someValue = RemotableObject.Instance.SomeDynamicValue;

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

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

Ответы [ 3 ]

30 голосов
/ 10 апреля 2009

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

затем, если ваш сервер «ServerName» и он прослушивает порт nnnn, а Uri - «MyMsgEndpointUri», вы определили Uri как:

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

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

RemotingServices.Marshal([singletonInstance], MesgURI);  

Вместо RegisterWellKnownServiceType();

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

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

С сервера просто вызовите статический метод фабрики ваших одноэлементных классов, чтобы получить доступ к этому одноэлементному экземпляру ... Не используйте вызовы удаленного взаимодействия вообще ...

0 голосов
/ 10 апреля 2009

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

0 голосов
/ 10 апреля 2009

номер

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

...