но также создает удаленный объект:
RemotingConfiguration.RegisterActivatedClientType(
typeof (Hello), 'tcp://localhost:8086/HelloServer');
Hello obj = new Hello();
Объекты прокси
Методы Activator.GetObject() и Activator.CreateInstance() возвращают клиенту прокси. На самом деле создается два прокси (прозрачный и реальный). Прозрачный прокси выглядит как удаленный объект, он реализует все открытые методы удаленного объекта, вызывая метод Invoke() реального прокси. Реальный прокси посылает сообщения в канал посредством приемников сообщений.
С помощью RemotingServices.IsTransparentProxy() проверяется, является ли объект на самом деле прозрачным прокси. Можно также добраться до реального прокси с помощью RemotingServices.GetRealProxy(). Используя отладчик, легко получить все свойства реального прокси:
ChannelServices.RegisterChannel(new TCPChannel());
Hello obj =
(Hello)Activator.GetObject(typeof(Hello), 'tcp://localhost:8086/Hi');
if (obj == null) {
Console.WriteLine('could not locate server');
return 0;
}
if (RemotingServices.IsTransparentProxy(Obj)) {
Console.WriteLine('Using a transparent proxy');
RealProxy proxy = RemotingServices.GetRealProxy(obj);
// proxy.Invoke(message);
}
Реальный прокси может заменяться специально созданным прокси. Специально созданный прокси расширяет базовый класс System.Runtime.Remoting.RealProxy. Мы получаем тип удаленного объекта в конструкторе специального прокси. Вызов конструктора для RealProxy создает прозрачный прокси в дополнение к реальному. В конструкторе могут быть доступны зарегистрированные каналы с помощью класса ChannelServices для создания приемника сообщений в методе IChannelSender.CreateMessageSink(). Помимо реализации конструктора, специальный канал переопределяет метод Invoke(). В Invoke() получают сообщение, которое затем анализируется и посылается в приемник сообщений.
Сообщения
Прокси посылает сообщение в канал. На серверной стороне будет сделан вызов метода после анализа сообщения, поэтому давайте рассмотрим сообщения.
Имеется несколько классов сообщений для вызова методов, ответов, возврата сообщений и т.д. Все классы сообщений должны реализовывать интерфейс IMessage. Этот интерфейс имеет единственное свойство: Properties. Это свойство представляет словарь, где URI указывает объект, а вызываемые MethodName, MethodSignature, TypeName, Args и CallContext являются пакетами.
Ниже представлена иерархия классов и интерфейсов сообщений:
Посылаемое реальному прокси сообщение является MethodCall. С помощью интерфейсов IMethodCallMessage и IMethodMessage мы имеем более простой доступ к свойствам сообщения, чем через интерфейс IMessage. Вместо использования интерфейса IDictionary мы имеем прямой доступ к имени метода, URI, аргументам и т.д. Реальный прокси возвращает ReturnMessage прозрачному прокси.
Приемники сообщений
Метод Activator.GetObject() вызывает RemotingServicesConnect() для соединения с хорошо известным объектом. В методе Connect() происходит Unmarshal (), где создается не только прокси, но и уполномоченные приемники. Прокси использует цепочку уполномоченных приемников для передачи сообщения в канал. Все приемники являются перехватчиками, которые могут изменять сообщение и выполнять некоторые дополнительные действия, такие как создание блокировки, запись события, выполнение проверки безопасности и т.д.
Все приемники событий реализуют интерфейс IMessageSink. Такой интерфейс определяет одно свойство и два метода:
□ Свойство NextSink используется приемником для получения следующего приемника и передачи сообщения дальше.
□ Для синхронных сообщений вызывается метод SyncProcessMessage() предыдущим приемником или удаленной инфраструктурой. Он имеет параметр IMessage для отправки и возврата сообщения.
□ Для асинхронных сообщений вызывается метод AsyncProcessMessage() предыдущим приемником в цепочке или удаленной инфраструктурой. AsyncProcessMessage() имеет два параметра, куда могут передаваться сообщение и приемник сообщения, который получает ответ.
Рассмотрим три доступных для использования приемника сообщения.
Уполномоченный приемник
Можно получить цепочку уполномоченных приемников с помощью интерфейса IEnvoyInfo. Маршализованная объектная ссылка ObjRef имеет свойство EnvoyInfo, которое возвращает интерфейс IEnvoyInfo. Список уполномоченных приемников создается из серверного контекста, поэтому сервер может добавлять функциональность клиенту. Уполномоченные приемники собирают информацию об идентичности клиента и предают ее серверу.
Приемник серверного контекста
