Ватсон Карли
Шрифт:
Некоторые из перезагруженных методов
Activator.CreateInstance
используются только для создания локальных объектов. Для получения удаленных объектов требуется метод, куда можно передавать activationAttributes
. Один из таких перезагруженных методов используется в примере. Этот метод получает два строковых параметра, первый из которых является именем сборки, второй — типом, а третий — массивом объектов. В объектном массиве канал и имя объекта определяются с помощью UrlAttribute
. Чтобы использовать класс UrlAttribute
, должно быть определено пространство имен System.Runtime.Remoting.Activation
. object [] attrs = { new UrlAttribute("tcp://localhost:8086/Hello") };
ObjectHandle handle =
Activator.CreateInstance("RemoteHello",
"Wrox.ProfessionalCSharp.Hello", attrs);
if (handle == null) {
Console.WriteLine("could not locate server");
return 0;
}
Hello obj = (Hello)handle.Unwrap;
Console.WriteLine(obj.Greeting("Christian"));
Конечно, для активизированных клиентом объектов также возможно использование оператора
new
вместо класса Activator
. Таким образом, мы должны зарегистрировать активизированный клиентом объект с помощью RemotingConfiguration.RegisterActivatedClientType
. В архитектуре активизированных клиентом объектов оператор new не только возвращает прокси, но также создает удаленный объект: 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
прозрачному прокси.