Аннотация
В статье описываются фундаментальные концепции инфраструктуры
удаленного взаимодействия - Microsoft .NET Remoting, основные компоненты
этой инфраструктуры, а также сценарии, в которых .NET Remoting можно
было бы применять для взаимодействия с распределенными объектами.
Примечание
В статье приводится исходный код, обновленный в соответствии с
требованиями версии Beta 2.
Содержание
Введение
Microsoft .NET Remoting - расширяемая инфраструктура с широкими
возможностями для бесшовного взаимодействия между объектами, которые
находятся в разных AppDomain'ах, в разных процессах или даже на разных
компьютерах. .NET Remoting представляет мощную и в то же время простую
модель программирования и поддержку периода выполнения, благодаря чему
удаленное взаимодействие становится прозрачными. В этой статье мы
рассмотрим различные строительные блоки, образующие архитектуру
Remoting, а также исследуем некоторые типичные сценарии применения .NET
Remoting. Обзор по .NET Remoting см. в
Microsoft .NET Remoting: A Technical Overview.
Объекты .NET Remoting
Существует три типа объектов, которые могут выступать в роли
удаленных объектов .NET (тип объекта выбирается в зависимости от
потребностей приложения).
- SingleCall-объекты
SingleCall-объекты обслуживают один - и только один - входящий
запрос. Они полезны, если вам нужны объекты, выполняющие строго
определенный объем работы. От SingleCall-объектов обычно не
требуется сохранения информации о состоянии, и сами по себе они не
способны сохранять такую информацию между вызовами методов. Зато
SingleCall-объекты можно настроить с учетом требований балансировки
нагрузки.
- Singleton-объекты
Singleton-объекты обслуживают несколько клиентов и, следовательно,
совместно используют данные, сохраняя информацию о состоянии между
клиентскими вызовами. Они полезны, если вам нужно, чтобы одни и те
же данные явно использовались несколькими клиентами, а также если
издержки, связанные с созданием и поддержкой объектов, велики.
- Объекты, активизируемые клиентом (CAO)
Объекты, активизируемые клиентом (Client-activated objects, CAO), -
это объекты на серверной стороне, активизируемые по запросу клиента.
Способ активизации этих серверных объектов во многом аналогичен
активизации соклассов в классической модели COM. Когда клиент с
помощью оператора new отправляет запрос к серверному объекту,
удаленному приложению посылается сообщение с запросом на
активизацию. Затем сервер создает экземпляр запрашиваемого класса и
возвращает ObjRef вызывающему клиентскому приложению. Далее на
клиентской стороне по полученному ObjRef создается прокси, через
который клиент будет вызывать методы удаленного объекта. Объекты,
активизируемые клиентом, могут сохранять информацию о состоянии
между вызовами методов для конкретного клиента, но не для разных
клиентских объектов. Каждый вызов new возвращает прокси для
независимого экземпляра типа, существующего на сервере.
Передача объектов по механизму .NET Remoting
.NET Remoting позволяет передавать объекты между приложениями
следующими способами.
- Как параметры методов.
Пример: public int myRemoteMethod (MyRemoteObject myObj)
- Как возвращаемые значения методов.
Пример: public MyRemoteObject myRemoteMethod(String
myString)
- Как свойства или поля .NET-компонентов.
Пример: myObj.myNestedObject
При передаче объектов с маршалингом по значению (Marshal By
Value, MBV) из одного приложения в другое создается полная копия
объекта.
При передаче объектов с маршалингом по ссылке (Marshal By
Reference, MBR) из одного приложения в другое создается ссылка на
объект. Когда удаленное приложение получает ссылку на объект (ObjRef),
она преобразуется в "прокси", обеспечивающий доступ к исходному объекту.
Пример кода для простого серверного объекта .NET Remoting
using System;
using System.Runtime.Remoting;
namespace myRemoteService
{
// Общеизвестный объект Web-сервиса
public class myRemoteObject : MarshalByRefObject
{
// Метод myRemoteMethod
public String myRemoteMethod(String s)
{
return "Hello World";
}
}
}
Пример клиентского кода для доступа к этому объекту
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using myRemoteService;
public class Client
{
public static int Main(string[] args)
{
ChannelServices.RegisterChannel(new HttpChannel());
// Создаем экземпляр класса myRemoteObject
myRemoteObject myObj = ( myRemoteObject)Activator.GetObject(typeof(myRemoteObject),
"http://myHost:7021/host/myRemoteObject.soap");
myObj. myRemoteMethod ("Hello World");
return 0;
}
}
Срок жизни, определяемый арендой
Для объектов, ссылки на которые передаются в другие приложения,
создается так называемая аренда (lease). Она характеризуется сроком
аренды (lease time); когда он истекает, объект отключается от
инфраструктуры .NET Remoting. После освобождения в AppDomain всех ссылок
на объект последний уничтожается во время следующего цикла сбора мусора.
Таким образом, срок жизни объекта определяется арендой.
Для объектов устанавливается срок аренды по умолчанию, но его можно
увеличить несколькими способами (чтобы объекты продолжали существовать,
если клиенту нужно хранить информацию о состоянии в одном и том же
серверном объекте).
- Серверный объект может установить неограниченное время аренды,
что указывает Remoting на то, что объект не уничтожается при сборе
мусора.
- Клиент может вызвать метод
RemotingServices.GetLifetimeService и выяснить срок аренды
серверного объекта, возвращаемый диспетчером аренды, который
принадлежит AppDomain. Получив объект Lease, клиент может вызвать
метод Lease.Renew, чтобы увеличить срок аренды.
- Клиент может зарегистрировать спонсора в диспетчере аренды
своего AppDomain для получения определенной аренды. Когда срок
аренды удаленного объекта истекает, диспетчер аренды обращается к
спонсору с запросом, нужно ли возобновлять аренду.
- Если установлено свойство ILease::RenewOnCallTime, каждый
вызов удаленного объекта увеличивает срок аренды на время, заданное
в свойстве RenewOnCallTime.
|
Объекты
SingleCall/Singleton |
Объекты, активизируемые
клиентом |
Код активизации на клиентской стороне (этот
код выполняется на клиенте)
Дополнительную информацию см. в разделе
Файлы конфигурации |
а) Activator.GetObject()
б) new() и CFG-файл
CFG-файл клиента ссылается на URL:
Foo= http://localhost:80/ObjectZone/Foo.soap |
а) Activator.CreateInstance()
б) new() и CFG-файл
CFG-файл клиента ссылается на URL. Например:
http://localhost:80/ObjectZone |
Активизация серверного объекта |
Сообщения активизации не отправляются по
сети, пока не будет выдан первый вызов какого-либо метода. |
Сообщение активизации отправляется на сервер,
когда клиент создает объект и на клиентской стороне генерируется
прокси. Поддерживаются конструкторы с параметрами. |
Срок жизни серверного объекта |
Срок жизни определяется конфигурацией
сервера. Может быть SingleCall или Singleton. Singleton-объекты,
как и объекты, активизируемые клиентом, управляются системой
контроля сроков жизни объектов. |
Жизнь объекта прекращается, когда происходит
одно из двух событий:
а) истекает срок аренды;
б) клиент утрачивает ссылку на серверный объект. |
Регистрация на серверной стороне |
а) Используется файл конфигурации для
указания типа (SingleCall или Singleton).
б) Используется API-функция RegisterWellKnownServiceType() для
регистрации типа. |
Используется файл конфигурации для экспорта
объекта, активизируемого клиентом.
Дополнительную информацию см. в разделе
Файлы конфигурации. |
Преимущества моделей |
а) Клиенты компилируются в соответствии с
метаданными Common Language Runtime, указанными в базовом классе
компонента или определении интерфейса.
б) Удобно выполнять строго определенное число операций на
серверной стороне.
в) SingleCall-объекты легко устанавливаются в системы с
балансировкой нагрузки, так как не хранят информацию о
состоянии.
г) Singleton-объекты могут хранить информацию о состоянии, общую
для нескольких клиентских объектов. |
а) "Сокласс" классической COM аналогичен
вызову серверного объекта.
б) Клиенты могут более гибко управлять сроком жизни серверных
объектов.
в) Клиенты могут передавать в создаваемый объект параметры
конструкторов.
г) Серверные объекты могут хранить информацию о состоянии для
конкретных клиентов между вызовами методов. |
Размещение объектов .NET Remoting
Объекты .NET Remoting могут размещаться следующим образом.
- В управляемом исполняемом файле
Объекты .NET Remoting могут размещаться в обычном .NET EXE-файле или
в управляемой службе.
- В IIS
Объекты, поддерживающие удаленное взаимодействие (Remoting objects),
могут размещаться в Internet Information Server (IIS). По умолчанию
такие объекты принимают сообщения по HTTP-каналу. Для размещения
объектов с поддержкой удаленного взаимодействия в IIS нужно создать
виртуальный корень и скопировать в него файл remoting.config.
Исполняемый файл или DLL с удаленным объектом следует поместить в
подкаталог bin каталога, на который указывает корень IIS. Важно
заметить, что имя корневого каталога IIS должно совпадать с со
значением элемента <application name>, указанным в файлах
конфигурации. Файл конфигурации Remoting загружается автоматически,
когда приложение получает первое сообщение. При таком размещении
объекты .NET Remoting могут использоваться как Web-сервисы.
Пример файла Remoting.cfg:
<configuration>
<system.runtime.remoting>
<application name="RemotingHello">
<service>
<wellknown mode="SingleCall"
type="Hello.HelloService, Hello"
objectUri="HelloService.soap" />
</service>
<channels>
<channel port="8000"
type="System.Runtime.Remoting.Channels.Http.HttpChannel,
System.Runtime.Remoting" />
</channels>
</application>
</system.runtime.remoting>
</configuration>
- В службах .NET-компонентов
Объекты .NET Remoting можно размещать в инфраструктуре служб
.NET-компонентов, что позволяет использовать такие возможности служб
COM+, как транзакции, JIT и создание пулов объектов.
Дополнительную информацию см. в Microsoft .NET Framework
Component Services, Part 1.
Channel Services (System.Runtime.Remoting.Channels)
Приложения .NET и AppDomain'ы взаимодействуют между собой посредством
сообщений. .NET Channel Services предоставляют транспортный механизм,
обеспечивающий это взаимодействие.
В .NET Framework поддерживаются HTTP и TCP-каналы, но сторонние фирмы
могут писать и подключать каналы собственной разработки. По умолчанию
HTTP-канал использует для взаимодействия протокол SOAP, а TCP-канал -
данные, передаваемые в пакетах (payload) в двоичном формате (Binary).
С помощью интерфейса IChannel можно подключать к Channel Services
каналы собственной разработки, создаваемые для интеграции гетерогенных
приложений.
Пример кода, загружающего Channel Services
public class myRemotingObj
{
HttpChannel httpChannel;
TcpChannel tcpChannel;
public void myRemotingMethod()
{
httpChannel = new HttpChannel();
tcpChannel = new TcpChannel();
ChannelServices.RegisterChannel(httpChannel);
// Регистрируем HTTP-канал
ChannelServices.RegisterChannel(tcpChannel);
// Регистрируем TCP-канал
}
}
Форматирующие объекты сериализации
(System.Runtime.Serialization.Formatters)
Форматирующие объекты (formatters) сериализации используются в .NET
для кодирования и декодирования сообщений, передаваемых между
приложениями и AppDomain'ами. В исполняющей среде .NET имеется два
встроенных форматирующих объекта: Binary
(System.Runtime.Serialization.Formatters.Binary) и SOAP
(System.Runtime.Serialization.Formatters.Soap).
Для подключения форматирующих объектов сериализации необходимо
реализовать интерфейс IRemotingFormatter и подключить его к каналу (о
каналах рассказывалось выше). Благодаря этому обеспечивается гибкий
выбор канала и форматирующего объекта, наилучшим образом отвечающих
потребностям приложения. Различные сочетания канала и форматирующего
объекта рассматриваются в последующих разделах этого документа.
Пример: вы можете работать с HTTP-каналом, использующим
форматирующий объект Binary, и TCP-каналом, использующим форматирование
SOAP.
Контексты удаленного взаимодействия
Контекст - это окружение объектов, использующих одни и те же
свойства исполняющей среды. Примерами атрибутов контекста являются
синхронизация и привязка потоков к процессорам (thread affinity). При
активизации .NET-объекта исполняющая среда проверяет его совместимость с
текущим контекстом. Если объект и текущий контекст несовместимы,
создается новый контекст. В одном и том же контексте одновременно может
выполняться несколько объектов, а в AppDomain'е может присутствовать
несколько контекстов.
Когда объект одного контекста вызывает объект другого контекста,
вызов всегда выполняется через прокси контекста и зависит от политики,
определяемой сочетанием свойств контекста. Контекст нового объекта
обычно выбирается в соответствии с метаданными, указываемыми в атрибутах
класса.
Классы, которые могут связываться с контекстом, называются контекстно
связываемыми классами (context-bound classes). Для таких классов можно
указать специальные атрибуты контекста. Атрибуты контекста являются
расширяемыми, так что можно создавать свои атрибуты и подключать их к
классу. Объекты, связываемые с контекстом, наследуются от класса
System.ContextBoundObject.
Метаданные и файлы конфигурации .NET Remoting
Метаданные
В .NET Framework для хранения информации о компонентах используются
метаданные и сборки, что делает возможным взаимодействие компонентов,
написанных на разных языках. В .NET Remoting метаданные применяются для
динамического создания прокси-объектов. В прокси-объектах, создаваемых
на клиентской стороне, содержатся те же члены, что и в исходных классах,
а реализации прокси-объектов просто передают все вызовы исходным
объектам через инфраструктуру .NET Remoting. Форматирующие объекты
сериализации используют метаданные, чтобы преобразовывать вызовы методов
в поточные данные и обратно.
Клиент может получить информацию с необходимыми для обращения к
удаленному объекту метаданными следующими способами.
- .NET-сборка серверного объекта. Серверный объект может
создать сборку с метаданными и передать ее клиентам. Клиентские
объекты могут обращаться к этой сборке на этапе компиляции. Это
очень удобно в замкнутых системах, когда клиент и сервер являются
управляемыми компонентами.
- Объект, поддерживающий удаленное взаимодействие, может
предоставить WSDL-файл (см.
Web Services Description Language (WSDL) 1.1), описывающий
объект и его методы. Любой клиент, способный читать и генерировать
SOAP-запросы в соответствии с содержащейся в WSDL-файле информацией,
может вызывать этот объект и взаимодействовать с ним по протоколу
SOAP. При работе с серверными объектами .NET Remoting для генерации
WSDL-файлов, выступающих в роли метаданных, можно применять утилиту
SOAPSUDS.EXE из состава .NET SDK. Этот способ удобен, когда
организация планирует предоставлять общедоступный сервис, который
могут использовать любые клиенты.
- .NET-клиенты могут использовать утилиту SOAPSUDS для загрузки с
сервера XML-схемы (генерируемой на сервере), чтобы создавать
исходные файлы или сборку, содержащие только метаданные (без кода).
Эти исходные файлы могут дополнительно подключаться при компиляции
клиентского приложения. Такой метод удобен при разработке
многоуровневых систем, в которых объекты одного уровня должны
обращаться к удаленным объектам другого уровня.
Файлы конфигурации
Файлы конфигурации (.config-файлы) используются, чтобы указывать для
объектов различную информацию, относящуюся к удаленному взаимодействию.
Обычно у каждого AppDomain имеется свой файл конфигурации. Применение
файлов конфигурации позволяет добиться прозрачности местонахождения.
Параметры, указываемые в .config-файлах, можно задавать и программным
способом. Основное преимущество файлов конфигурации в том, что они
позволяют отделить информацию о конфигурации от кода клиента, так что,
если в будущем произойдут какие-то изменения, вы просто измените
.config-файл, не модифицируя и не перекомпилируя исходный файл. Файлы
конфигурации используются как клиентскими, так и серверными объектами
.NET Remoting.
Типичный файл конфигурации, помимо всего прочего, содержит следующую
информацию:
- информацию о хост-приложении;
- имена объектов;
- URI объектов;
- регистрируемые каналы (можно зарегистрировать несколько каналов
сразу);
- информацию о сроке аренды для серверных объектов.
Ниже показан пример файла конфигурации (пожалуйста, обратите
внимание, что в будущих версиях этот формат может измениться на XML):
<configuration>
<system.runtime.remoting>
<application name="HelloNew">
<lifetime leaseTime="20ms" sponsorshipTimeout="20ms"
renewOnCallTime="20ms" />
<client url="http://localhost:8000/RemotingHello">
<wellknown type="Hello.HelloService, MyHello"
url="http://localhost:8000/RemotingHello/HelloService.soap" />
<activated type="Hello.AddService, MyHello"/>
</client>
<channels>
<channel port="8001"
type="System.Runtime.Remoting.Channels.Http.HttpChannel,
System.Runtime.Remoting" />
</channels>
</application>
</system.runtime.remoting>
</configuration>
Сценарии применения .NET Remoting
Итак, вы получили представление о том, как работает .NET Remoting.
Теперь исследуем различные ситуации и посмотрим, как лучше применять
.NET Remoting в каждой из этих ситуаций. В следующей таблице приведен
список возможных сочетаний клиента и сервера, а также используемые по
умолчанию протокол и тип полезных данных. Пожалуйста, не забывайте, что
инфраструктура .NET Remoting расширяема и позволяет создавать
собственные коммуникационные каналы и форматирующие объекты
сериализации.
Клиент |
Сервер |
Полезные данные |
Протокол |
.NET-компонент |
.NET-компонент |
SOAP/XML |
http |
.NET-компонент |
.NET-компонент |
Binary |
TCP |
Управляемый/неуправляемый код |
Web-сервис для платформы .NET |
SOAP/XML |
http |
.NET-компонент |
Неуправляемый COM-компонент |
NDR (Network Data Representation) |
DCOM |
Неуправляемый COM-компонент |
.NET-компонент |
NDR |
DCOM |
Любой клиент <-> .NET по протоколам HTTP-SOAP
Web-сервис - это адресуемый с помощью URL ресурс, программно
возвращающий информацию клиентам, которые ее запрашивают. Клиенты могут
обращаться к Web-сервисам, не заботясь о том, как реализованы
Web-сервисы. Web-сервисы используют строго определенные интерфейсы,
называемые контрактами и описываемые в WSDL-файлах (Web Services
Description Language). Дополнительную информацию о WSDL см. в
Web Services Description Language (WSDL) 1.0.
Можно добиться того, чтобы клиенты обращались к объектам .NET
Remoting как к Web-сервисам, разместив эти объекты в IIS. Любой клиент,
способный считать информацию из WSDL-файла, может вызывать удаленные
объекты по протоколу SOAP в соответствии с контрактом, описанным в
WSDL-файле. IIS с помощью ISAPI-расширений направляет запрос к
соответствующему объекту. Таким образом, объект Remoting может
функционировать как объект Web-сервиса и использовать богатые
возможности инфраструктуры .NET Framework. Эта конфигурация удобна в
случаях, когда к объектам нужно обращаться из программ, работающих на
разных платформах/средах. Дополнительную информацию по Web-сервисам см.
в
The Programmable Web: Web Services Provides Building Blocks for the
Microsoft .NET Framework. Такая конфигурация облегчает
взаимодействие клиентов с разрабатываемыми вами .NET-объектами через
брандмауэр.
|
Client |
Клиент |
UNIX/Windows
/Mainframe using WSDL |
UNIX/Windows
/Мэйнфрейм с использованием WSDL |
Firewall |
Брандмауэр |
Remoting Object |
Объект Remoting |
Рис. 1. Пример вызова клиентом Web-сервиса объекта Remoting через
HTTP-SOAP
.NET<->.NET по HTTP/SOAP-каналу
HTTP-канал по умолчанию использует форматирующий объект SOAP,
следовательно этот канал можно задействовать в ситуациях, когда клиенты
обращаются к объектам через Интернет. Так как применяется протокол HTTP,
эта конфигурация допускает удаленное обращение к .NET-объектам через
брандмауэр. Объекты, к которым предоставляется доступ, несложно
сконфигурировать как объекты Web-сервисов, просто разместив их в IIS (об
этом рассказывалось в предыдущем разделе). Тогда клиенты смогут
считывать WSDL-файлы этих объектов и взаимодействовать с удаленными
объектами по протоколу SOAP.
.NET<->.NET по TCP-каналу
TCP-канал по умолчанию использует двоичный форматирующий объект,
сериализующий данные в двоичном виде и применяющий для передачи данных
по сети простые сокеты. Этот метод идеален, если объект устанавливается
в замкнутой среде, ограниченной брандмауэром. Такой подход более
эффективен, так как для обмена двоичными данными между объектами
используются сокеты. Преимущество использования TCP-канала для доступа к
объектам заключается в низких издержках при работе в замкнутой среде.
Такой подход неприменим при доступе к объектам через Интернет из-за
проблем конфигурирования и передачи данных через брандмауэр.
|
Client |
Клиент |
TCP Binary |
TCP Binary |
Remoting Object |
Объект Remoting |
Machine 1 |
Компьютер 1 |
Machine 2 |
Компьютер 2 |
Рис. 2. Пример вызова клиентом по TCP-каналу объекта Remoting,
находящегося на другом компьютере
.NET <-> неправляемый COM-компонент <-> .NET
COM Interop Services позволяет вызывать неуправляемые компоненты,
написанные в соответствии с классической моделью COM. Когда клиентский
объект .NET Remoting создает экземпляр COM-объекта, доступ к COM-объекту
осуществляется через оболочку, вызываемую исполняющей средой (runtime
callable wrapper, RCW) и выполняющую функции прокси для неуправляемых
объектов. Эти оболочки выглядят для .NET-клиента так же, как любые
другие управляемые классы, но в действительности они выполняют маршалинг
вызовов между управляемым (.NET) и неуправляемым (COM) кодом.
Аналогичным образом можно предоставить доступ к серверному объекту
.NET Remoting классическим COM-клиентам. Когда COM-клиент создает
экземпляр .NET-объекта, доступ к нему осуществляется через оболочку,
вызываемую COM-объектами (COM callable wrapper, CCW) и выступающую в
роли прокси для управляемого объекта.
И в том, и в другом случае для взаимодействия используется DCOM. Это
очень удобно в ситуациях при наличии смешанной среды из COM- и
.NET-компонентов.
Заключение
Microsoft .NET Framework предоставляет мощную, расширяемую и
независимую от конкретного языка программирования инфраструктуру,
позволяющую разрабатывать надежные и масштабируемые распределенные
системы. Инфраструктура .NET Remoting поддерживает эффективные механизмы
удаленного взаимодействия, из которых можно выбрать наиболее
соответствующие требованиям к вашей системе. .NET Remoting обеспечивает
бесшовную интеграцию с Web-сервисами и позволяет создавать .NET-объекты,
к которым можно обращаться с разных платформ.
Дополнительные материалы