DCOM (курсовая работа) (548068), страница 3
Текст из файла (страница 3)
Для выдающего запрос клиента оба протокола выглядят совершенноодинаково, хотя нижележащие транспортные протоколы ведут себя абсолютно по-разному. Этиразличия скрываются соответствующим протоколом RPC.Независимо от используемого протокола клиент должен обладать информацией связывания(binding information) с пунктом назначения, прежде чем он выполнит вызов ORPC. В составе этойинформации обычно сетевой адрес удаленной машины (например, адрес IP) и указание, какаякомбинация протоколов должна использоваться (например, CL RPC и UDP). Информация связыванияможет включать точку назначения транспорта (transport endpoint) — ее часто называют портом —задающую конкретный процесс на удаленной машине.
Информацию связывания удобно представлятькак строковое связывание (string binding) — символьной строкой, содержащей всю необходимуюинформацию.Информацию связывания с данной удаленной системой клиент может получить по-разному.Например, имя машины, передаваемое функции CoCreateInstanceEx, может быть использовано дляопределения по крайней мере части информации связывания. Кроме того, возможна передачаинформации связывания (или ссылки на нее) от одного объекта другому. Чтобы понять, как этоработает и почему это важно, сначала необходимо разобраться с ролью, которую играют OXID иразрешатели OXID.OXID и разрешатели OXIDСервер, реализующий один или несколько объектов СОМ, доступных клиентам на другихмашинах, можно рассматривать как экспортер объектов (object exporter). Разрешая удаленным клиентамдоступ к своим объектам, сервер в некотором смысле "экспортирует" эти объекты, обеспечивая ихмежмашинное использование.
Если сервер — однопоточный процесс с одним или несколькимиобъектами, то в качестве экспортера выступает сервер в целом. Если же сервер — многопоточныйпроцесс с одной или несколькими комнатами (apartment), содержащими различные объекты, тоэкспортером является каждая из комнат. В любом случае каждому экспортеру объектов присваивается8-байтовое значение — идентификатор экспортера объектов (OXID — Object Exporter Identifier).Заметьте: у одного процесса с несколькими комнатами может быть несколько OXID.6Для доступа к удаленному объекту клиент вначале должен получить его OXID (как этоделается, объясняется в следующем разделе.) Имея OXID, клиент может использовать разрешательOXID для отображения OXID в информацию связывания с объектом. На любой машине,поддерживающей DCOM, имеется разрешатель OXID (OXID resolver), и каждый разрешатель OXIDподдерживает интерфейс lObjectExporter (название этого интерфейса, уходящее своими корнями висторию DCOM, несколько неудачно, так как он не реализуется экспортером объектов).
Несмотря насвое СОМ-подобное имя, IObjectExporter не является интерфейсом СОМ. На самом деле это интерфейсRPC, и обращение к нему выполняется через вызовы чистого RPC, а не вызовы ORPC. В его составе 3"метода": ResolveOXID, SimplePing и ComplexPing.Каждый разрешатель OXID поддерживает таблицу OXID и их строковых связывании. Какминимум, данная таблица содержит запись для каждого исполняющегося на данной машине объекта,имеющего клиента вне своего процесса или комнаты. Она обычно включает и некоторые OXID истроковые связывания для объектов, исполняющихся на других машинах. Чтобы понять почему,рассмотрим, как осуществляется передача указателей на интерфейсы между машинами.OBJREF: передача указателей интерфейсовКак и вызов локального метода, вызов удаленного метода может содержать параметры.
Норазные машины иногда используют для представления одних и тех же данных разные форматы.Например, многие системы для представления символов применяют ASCII, тогда как мэйнфреймы IBMприменяют для этого код EBCDIC. А разные компьютеры используют разные форматы представленияцелых и вещественных чисел. Для обеспечения взаимодействия машин, применяющих разные форматыданных, выполняется маршалинг параметров вызова ORPC с использованием сетевого формата NDR(Network Data Representation). NDR — стандартная часть DCE RPC (и, конечно же, MS RPC) —обеспечивает эффективный способ передачи параметров практически любых типов СОМ IDL междумашинами, использующими разные представления этих типов данных. Необходимая трансляцияпараметров из NDR в локальное представление выполняется машиной, принимающей вызов.Однако один тип параметров, часто передаваемый в вызовах ORPC, не имеет прямойподдержки NDR — это указатели на интерфейсы.
Объекты часто передают указатели на интерфейсысвоим клиентам, а клиент имеет право передать имеющийся у него указатель на интерфейс любомудругому объекту. Когда указатель на интерфейс ссылается на объект в том же процессе, проблем невозникает: указатель передается, как есть. Когда указатель на интерфейс ссылается на объект в другомпроцессе на той же машине, передается ссылка на данный интерфейс внутри соответствующегопроцесса.
Но когда указатель на интерфейс ссылается на объект, расположенный на другой машине, то,что должно быть передано, является весьма сложной конструкцией — объектной ссылкой (objectreference — OBJREF).• Согласно протоколу DCOM в состав OBJREF входят:• OXID;• уникальный идентификатор данного интерфейса объекта — идентификатор указателяинтерфейса (interface pointer identifier — IPID);• идентификатор объекта (object identifier — OID), определяющий объект;• строковое связывание для разрешателя OXID на той машине, где исполняется объект.После передачи OBJREF от одного объекта другому принимающий объект может вызыватьметоды с помощью указателя на интерфейс, представляемого данной OBJREF.Но как объект, получающий указатель на интерфейс, определяет, как связаться с объектом,заданным этим указателем? Точнее, откуда берется информация связывания с объектом, не являющаясячастью самой OBJREF? Есть два варианта.
Если любой объект на локальной машине уже связывалсянедавно с объектом, имеющим тот же OXID, что и объект, на который ссылается указатель, то данныйOXID уже есть в таблице локального разрешателя OXID. Если же информация связывания в таблицеотсутствует, ее надо запросить у машины, на которой исполняется объект, заданный данной OBJREF.Чтобы получить необходимую для использования новой OBJREF информацию связывания,DCOM на машине клиента, получившего OBJREF, обращается за помощью к локальному разрешателюOXID, передавая ему эту OBJREF. (Все это, конечно, скрыто от программиста и является частьюинфраструктуры, обеспечиваемой DCOM.) Разрешатель OXID выделяет OXID из OBJREF и пытаетсяотыскать его в собственной таблице OXID.
Если объект с тем же OXID уже используется кем-то на этой7машине, то в таблице будет запись для данного OXID с необходимым строковым связыванием.Предположим, объект А получил OBJREF интерфейса, поддерживаемого объектом X, расположеннымна другой машине. Чтобы получить информацию связывания для осуществления вызовов с помощьюнового указателя, реципиент передает OBJREF своему локальному разрешателю OXID. РазрешательOXID может сразу возвратить нужную информацию, если она уже есть в его таблице.Однако допустим, что OBJREF ссылается на интерфейс удаленного объекта Q, для которого улокального разрешателя OXID информации нет. Тогда разрешатель OXID извлекает из OBJREFинформацию связывания с разрешателем OXID на машине, где исполняется объект Q, и с помощью еесвязывается с этим разрешателем.
Для этого локальный разрешатель OXID вызывает метод ResolveOxidинтерфейса lObjectExporter разрешателя OXID на удаленной машине. В качестве параметра этоговызова передается OXID, выделенный из только что полученной OBJREF. Данный вызов возвращаетстроковое связывание для данного OXID, которое затем добавляется локальным разрешателем в своютаблицу. Вновь полученный указатель на интерфейс теперь можно использовать.Здесь возникает естественный вопрос: почему в составе OBJREF передается не строковоесвязывание самого объекта, но связывание разрешателя OXID на машине объекта? Ведь тогдаклиентскому разрешателю OXID вообще не пришлось бы связываться с разрешателем OXID объекта —полученная OBJREF уже содержала бы все необходимое для связи с объектом.Чтобы понять, почему архитекторы DCOM приняли иное решение, вспомним, что DCOMпозволяет клиенту работать с удаленным объектом с помощью разных протоколов: TCP/IP, UDP/IP,IPX/SPX и др.
Для каждого поддерживаемого объектом протокола может потребоваться загрузкаотдельной DLL, которой обычно необходимы дополнительные потоки для ожидания поступлениязапросов по данному протоколу. Так что объекту, работающему с несколькими протоколами, это можетдорого обойтись. Не удивительно, что архитекторы DCOM стремились снизить накладные расходы,загружая протоколы только тогда, когда это необходимо, и пытаясь обойтись их минимальнымколичеством.С этой целью объекты используют отложенную регистрацию протоколов (lazy protocolregistration).
Другими словами, объект загружает необходимый для протокола код, лишь когда клиентзахочет работать с ним по данному протоколу. Например, когда разрешатель OXID объекта получает отклиентской машины вызов IObjectExporter::ResolveOxid, этот запрос выполняется с помощьюпротокола, скажем, TCP/IP. Разрешатель OXID на машине объекта может определить, загружен ли ужеобъектом код TCP/IP. Если нет, разрешатель приказывает объекту загрузить соответствующий код,после чего клиент и объект могут взаимодействовать по TCP/IP. Если затем другой разрешатель OXIDзапросит связь с тем же объектом по UDP/IP, объект получит указание загрузить код и этого протокола.В то время как разрешатели OXID обязаны ожидать вызовы по всем протоколам, поддерживаемымданной машиной, конкретный объект загружает код только протоколов, явно запрошенных егоклиентами.
Данный подход иногда требует дополнительного обмена данными при установлениисоединения, но он позволяет объектам избежать напрасной траты ресурсов на не используемые имипротоколы.Роль SCMПри создании объекта на той же машине, что и клиент, библиотека СОМ этой машиныпредоставляет выполнение основной работы по запуску соответствующего сервера диспетчерууправления сервисами (Service Control Manager — SCM).
Когда же объект создается на удаленноймашине, SCM клиентской машины должен в свою очередь делегировать выполнение этой задачи SCMудаленной машины. Для обеспечения стандартной схемы, позволяющей SCM связываться со своиманалогом на удаленной машине, все SCM поддерживают интерфейс IActivation.Иначе говоря, SCM запрашивает создание объекта у SCM на другой машине через интерфейсIActivation. Очень простой интерфейс IActivation содержит единственную операцию —RemoteActivation, используемую для активизации объектов, создаваемых любыми описанными ранееспособами.Оптимизация IUnknownКаждый объект СОМ обязан поддерживать IUnknown — это не менее справедливо дляобъектов, доступ к которым осуществляется по сети. Но если бы каждый вызов клиентом метода8lUnknown транслировался непосредственно в вызов ORPC объекта, результатом почти наверняка былабы неприемлемая производительность.
В связи с этим DCOM обеспечивает оптимизацию этих важныхметодов.В основе этой оптимизации лежат объекты OXID (OXID objects), каждый из которыхподдерживает интерфейс IRemUnknown. Как уже отмечалось, OXID идентифицирует группу объектов,с которыми можно связаться через данное строковое связывание. Все такие объекты представленыодним объектом OXID и, следовательно, одним IRemUnknown. Все удаленные вызовы методов всехIUnknown таких объектов вначале обрабатываются интерфейсом IRemUnknown соответствующегообъекта OXID.Интерфейс IRemUnknown аналогичен, но не эквивалентен IUnknown.