□ System.Runtime.Serialization.Formatters.Soap.SoapFormatter
.
Форматтер ассоциируется с каналом из-за наличия объектов приемников форматтера и провайдеров источников форматтера.
Оба эти класса форматтера реализуют интерфейс System.Runtime.Remoting.Messaging.IRemotingFormatter
, который определяет методы Serialize()
и Deserialize()
для передачи и приема данных из канала.
Форматтер является подключаемым. При создании класса собственного форматтера экземпляр должен ассоциироваться с используемым каналом. Это делается с помощью приемника форматтера и провайдера приемника форматтера. Как было показано ранее, провайдер источника форматтера, например SoapServerFormatterSinkProvider
, может передаваться как аргумент при создании канала. Провайдер источника форматтера реализует для сервера интерфейс IServerChannelSinkProvider
, а для клиента IClientChannelSinkProvider
. Оба эти интерфейса определяют метод CreateSink()
, возвращающий источник форматтера, — SoapServerFormatterSinkProvider
даст экземпляр класса SoapServerFormatterSink
. На клиентской стороне имеется класс SoapClientFormatterSink
, который использует в методах SyncProcessMessage()
и AsyncProcessMessage()
класс SoapFormatter
для сериализации сообщения. SoapServerFormatterSink
десериализует сообщение снова с помощью SoapFormatter
.
Все эти классы приемника и провайдера способны расширяться и заменяться собственными реализациями.
ChannelServices и RemotingContiguration
Служебный класс ChannelServices
используется для регистрации каналов в среде выполнения .NET Remoting. С помощью этого класса можно также получить доступ ко всем зарегистрированным каналам. Это крайне полезно, если для конфигурирования канала используются конфигурационные файлы, так как в этом случае канал создается неявно (см. ниже).
Канал регистрируется с помощью статического метода ChannelServices.RegisterChannel()
.
Здесь представлен серверный код для регистрации каналов HTTP и TCP:
TcpChannel tcpChannel = new TcpChannel(8086);
HttpChannel httpChannel = new HttpChannel(8085);
Channel Services.RegisterChannel(tcpChannel);
СhannelServices.RegisterChannel(httpChannel);
Служебный класс ChannelServices
можно теперь использовать для отправки синхронных и асинхронных сообщений и для отмены регистрации определенных каналов. Свойство RegisteredChannels
возвращает массив IChannel
всех зарегистрированных каналов. Возможно также и< пользование метода GetChannel()
для доступа к определенному каналу по его имени. С помощью ChannelServices
пишется специальная административная утилита для управления каналами. Вот небольшой пример показывающий как можно остановить режим прослушивания канала:
HttpServerChannel channel =
(HttpServerChannel)ChannelServices.GetChannel('http');
channel.StorListening(null);
Класс RemotingConfiguration
— другой служебный класс .NET Remoting
. На серверной стороне он используется для регистрации типов удаленных объектов активированных на сервере объектов и для маршализации удаленных объектов в ссылочный класс маршализованного объекта ObjRef
. ObjRef
является сериализуемым представлением объекта, которое было послано по линии связи. На клиентской стороне работает RemotingServices
, демаршализуя удаленный объект, чтобы создать прокси из объектной ссылки.
Вот серверный код для регистрации хорошо известного типа удаленного объекта в RemotingServices
:
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(Hello), // Тип
'Hi', // URI
WellKnownObjectMode.SingleCall); // Режим
Первый аргумент метода RegisterWellKnownServiceType()
— Wrox.ProfessionalCSharp.Hello
определяет тип удаленного объекта. Второй аргумент — Hi
является универсальным идентификатором ресурса удаленного объекта, который используется клиентом для доступа к удаленному объекту. Последний аргумент — режим удаленного объекта. Режим может быть значением перечисления WellKhownObjectMode
: SingleCall
или Singleton
.
□ SingleCall
означает, что объект не сохраняет состояние. Для каждого вызова удаленного объекта создается новый экземпляр. Объект SingleCall
создается на сервере с помощью метода RemotingConfiguration.RegisterWellKnownServiceТуре()
и аргумента WellKnownObjectMode.SingleCall
. Это очень эффективно для сервера, так как получается, что не требуется поддерживать ресурсы может быть для тысяч клиентов.
□ С помощью режима Singleton объект совместно используется всеми клиентами сервера. Такие объектные типы могут применяться, если желательно предоставить доступ к некоторым данным всем клиентам. Это не должно быть проблемой для читаемых данных, но для данных чтения-записи необходимо знать о вопросах блокировки и масштабируемости. Объект Singleton
создается на сервере с помощью метода RemotingConfiguration.RegisterWellKnownServiceType()
и аргумента WellKnownObjectMode.Singleton
. Необходимо убедиться, что данные не могут быть повреждены, когда клиенты получают доступ одновременно, но нужно и проверять, что блокирование сделано достаточно эффективно для достижения требуемой масштабируемости.
Сервер для активизированных клиентом объектов
Если удаленный объект должен хранить состояние для определенного клиента, то можно использовать активизированные клиентом объекты. В следующем разделе будут рассмотрены возможности клиентской стороны. В частности, как вызывать объекты, активизированные сервером, и объекты, активизированные клиентом. На серверной стороне активизированные клиентом объекты должны регистрироваться по-другому, чем объекты, активизированные сервером.
Вместо вызова RemotingConfiguration.RegisterWellKnownType()
необходимо вызвать RemotingServices.RegisterActivatedServiceType()
. С помощью этого метода определяются только типы, но не URI. Причина этого заключается в том, что для активированных клиентом объектов создаются экземпляры различных объектных типов с помощью одного URI. URI для всех активированных клиентом объектов должен быть определен с помощью RemotingConfiguration.ApplicationName
:
RemotingConfiguration.ApplicationName = 'HelloServer';