Если удаленный объект должен хранить состояние для определенного клиента, то можно использовать активизированные клиентом объекты. В следующем разделе будут рассмотрены возможности клиентской стороны. В частности, как вызывать объекты, активизированные сервером, и объекты, активизированные клиентом. На серверной стороне активизированные клиентом объекты должны регистрироваться по-другому, чем объекты, активизированные сервером.
Вместо вызова
RemotingConfiguration.RegisterWellKnownType
необходимо вызвать
RemotingServices.RegisterActivatedServiceType
. С помощью этого метода
определяются только типы, но не URI. Причина этого заключается в том, что для активированных клиентом объектов создаются экземпляры различных объектных типов с помощью одного URI. URI для всех активированных клиентом объектов должен быть определен с помощью
Для клиентов возможно использование и создание удаленных объектов с помощью класса
Activator
. Мы можем получить прокси для активированного сервером или хорошо известного удаленного объекта с помощью метода
GetObject
. Метод
CreateInstance
возвращает прокси для активированного клиентом удаленного объекта.
Вместо класса
Activator
для активации удаленных объектов используется также оператор new. Чтобы сделать это, удаленный объект должен конфигурироваться внутри клиента с помощью класса
RemotingConfiguration
.
URL-приложения
Во всех сценариях активации необходимо определять URL удаленного объекта. Этот URL является тем же самым, что и в браузере Web. Первая часть определяет протокол, за которым следует имя сервера или адрес IP, номер порта и URI, определенный при регистрации удаленного объекта на сервере в таком виде:
protocol://server:port/URI
Мы все время используем в нашем коде два примера URL: определяем протокол
http
и
tcp
, имя сервера
localhost
, номер порта 8085 и 8086, и
URI
как
Hi
, что дает нам запись:
http://localhost:8085/Hi
tcp://localhost:8086/Hi
Активация хорошо известных объектов
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
/// ...
TcpClientChannel channel = new TcpClientChannel;
ChannelServices.RegisterChannel(channel);
Hello obj = (Hello)Activator.GetObject(
typeof(Hello), "tcp://localhost:8086/Hi");
GetObject
является статическим методом класса
System.Activator
, который вызывает метод
RemotingServices.Connect
для возврата объекта прокси удаленному объекту. Первый аргумент определяет тип удаленного объекта. Прокси реализует все открытые и защищенные методы и свойства, так что клиент может вызывать эти методы так же, как для реального объекта. Второй аргумент является URL удаленного объекта. Здесь используется строка
tcp://localhost:8086/Hello
,
где
tcp
— протокол,
localhost:8086
— имя хоста и номер порта и, наконец,
Hello
— это URI объекта, который был определен с помощью
Если вы предпочитаете задать просто оператор new для активизации хорошо известных удаленных объектов, то удаленный объект можно зарегистрировать на клиенте с помощью все того же
RemotingConfiguration.RegisterWellKnownClientType
. Здесь понадобятся похожие аргументы: тип удаленного объекта и URI. Теперь можно использовать оператор new, который на самом деле не создает новый удаленный объект, а возвращает прокси аналогично
Activator.GetObject
. Если удаленный объект регистрируется с флажком
WellKnownObjectMode.SingleCall
, правило остается тем же самым: удаленный объект создается с каждым вызовом метода:
Удаленные объекты могут хранить состояние для клиента.
Activator.CreateInstance
создает активированный клиентом удаленный объект. С помощью метода
Activator.GetObject
удаленный объект создается при вызове метода и разрушается, когда метод заканчивается. Объект не хранит состояние сервера. В этом отличие от
Activator.CreateInstance
. С помощью статического метода
CreateInstance
запускается последовательность активации для создания удаленного объекта. Этот объект живет, пока не закончится время аренды и не произойдет сборка мусора. Позже мы рассмотрим механизм аренды.
Некоторые из перезагруженных методов
Activator.CreateInstance
используются только для создания локальных объектов. Для получения удаленных объектов требуется метод, куда можно передавать
activationAttributes
. Один из таких перезагруженных методов используется в примере. Этот метод получает два строковых параметра, первый из которых является именем сборки, второй — типом, а третий — массивом объектов. В объектном массиве канал и имя объекта определяются с помощью
UrlAttribute
. Чтобы использовать класс
UrlAttribute
, должно быть определено пространство имен
System.Runtime.Remoting.Activation
.
object [] attrs = { new UrlAttribute("tcp://localhost:8086/Hello") };