
- •Глава 2 Связь
- •2.1. Уровни протоколов
- •2.1. Уровни протоколов 83
- •84 Глава 2. Связь
- •2.1. Уровни протоколов 85
- •2.1.1. Низкоуровневые протоколы
- •86 Глава 2. Связь
- •2.1. Уровни протоколов 87
- •2.1.2. Транспортные протоколы (метод_Метелап лр_1)
- •88 Глава 2. Связь
- •2.1. Уровни протоколов 89
- •92 Глава 2. Связь
- •2.1.3. Протоколы верхнего уровня
- •2.1. Уровни протоколов 91
- •92 Глава 2. Связь
- •2.2. Удаленный вызов процедур 93
- •2.2. Удаленный вызов процедур
- •94 Глава 2. Связь
- •2.2.1. Базовые операции rpc
- •2.2. Удаленный вызов процедур 95
- •96 Глава 2. Связь
- •2.2. Удаленный вызов процедур 97
- •98 Глава 2. Связь
- •2.2.2. Передача параметров
- •2.2. Удаленный вызов процедур 99
- •100 Глава 2. Связь
- •2.2. Удаленный вызов процедур 101
- •102 Глава 2. Связь
- •2.2. Удаленный вызов процедур 103
- •2 .2.3. Расширенные модели rpc
- •104 Глава 2. Связь
- •2.2. Удаленный вызов процедур 105
- •106 Глава 2. Связь
- •2.2.4. Пример — dce rpc
- •2.2. Удаленный вызов процедур 107
- •108 Глава 2. Связь
- •2.2. Удаленный вызов процедур 109
- •110 Глава 2. Связь
- •2.3. Обращение к удаленным объектам 111
- •2.3. Обращение к удаленным объектам
- •112 Глава 2. Связь
- •2.3.1. Распределенные объекты
- •2.3. Обращение к удаленным объектам 113
- •114 Глава 2. Связь
- •2.3.2. Привязка клиента к объекту
- •2.3. Обращение к удаленным объектам 115
- •116 Глава 2. Связь
- •2.3. Обращение к удаленным объектам 117
- •2.3.3. Статическое и динамическое удаленное обращение к методам
- •118 Глава 2. Связь
- •2.3.4. Передача параметров
- •2.3. Обращение к удаленным объектам 119
- •120 Глава 2. Связь
- •2.3.5. Пример 1 — удаленные объекты dce
- •2.3. Обращение к удаленным объектам 121
- •122 Глава 2. Связь
- •2.3.6. Пример 2 — Java rmi
- •2.3. Обращение к удаленным объектам 123
- •124 Глава 2. Связь
- •2.3. Обращение к удаленным объектам 125
- •126 Глава 2. Связь
- •2.4. Связь посредством сообщений
- •2.4.1. Сохранность и синхронность во взаимодействиях
- •2 .4. Связь посредством сообщений 127
- •128 Глава 2. Связь
- •2.4. Связь посредством сообщений 129
- •130 Глава 2. Связь
- •2.4. Связь посредством сообщений 131
- •2.4.2. Нерезидентная связь на основе сообщений
- •132 Глава 2. Связь
- •2.4. Связь посредством сообщений 133
- •134 Глава 2. Связь
- •2.4. Связь посредством сообщений 135
- •136 Глава 2. Связь
- •2.4.3. Сохранная связь на основе сообщений
- •2.4. Связь посредством сообщений 137
- •1 38 Глава 2. Связь
- •2.4. Связь посредством сообщений 139
- •140 Глава 2. Связь
124 Глава 2. Связь
и спользования синхронизированных методов удаленные объекты невозможно защитить от одновременного доступа процессов, работающих через разные заместители. Вместо этого следует использовать явные методы распределенной блокировки.
Обращение к удаленным объектам в Java
Поскольку разница между локальными и удаленными объектами на уровне языка слабо заметна, Java может в ходе обращений к удаленным методам скрывать большую часть различий между ними. Так, в ходе обращения RMI в качестве параметра может быть передан любой простой или объектный тип, что предполагает возможность маршалинга типов. В терминологии Java это означает, что типы сериализуемы (serializable). Хотя в принципе сериализации можно подвергнуть большинство объектов, она не всегда является допустимой или возможной. Обычно зависящие от платформы объекты, такие как дескрипторы файлов или сокеты, не сериализуются.
Единственное различие между локальными и удаленными объектами, наблюдаемое в процессе RMI, состоит в том, что локальные объекты передаются по значению (включая большие объекты, такие как массивы), в то время как удаленные объекты передаются по ссылке. Другими словами, локальные объекты копируются, после чего копия используется в качестве параметра-значения. В случае удаленных объектов в качестве параметра используется ссылка на объект, без всякого копирования, как показано на рис. 2.17.
При обращении RMI в Java ссылка на удаленный объект реализуется именно так, как мы говорили в пункте 2.3.2. Эта ссылка содержит сетевой адрес и конечную точку сервера, а также локальный идентификатор необходимого объекта в адресном пространстве сервера. Как мы обсуждали, в ссылке на удаленный объект, кроме того, кодируется стек протоколов, используемых клиентом и сервером для взаимодействия. Чтобы понять, как при обращении RMI в Java кодируется стек протоколов, необходимо учитывать, что каждый объект Java представляет собой экземпляр класса. Класс же, в свою очередь, содержит реализацию одного или более интерфейсов.
В сущности, удаленный объект построен из двух различных классов. Один из классов содержит реализацию кода сервера и называется классом сервера. Класс сервера содержит реализацию той части удаленного объекта, которая выполняется на сервере. Другими словами, она содержит описание состояния (данных) объекта, а также реализацию методов обработки этого состояния. Из спецификации интерфейса объекта генерируется серверная заглушка, то есть скелетон.
Другой класс содержит реализацию кода клиента и называется классом клиента. Класс клиента содержит реализацию заместителя. Как и скелетон, этот класс также автоматически создается из спецификации интерфейса объекта. В своей простейшей форме заместитель делает только одну вещь — превращает каждый вызов метода в сообщение, пересылаемое реализации удаленного объекта, находящейся на сервере, а каждое ответное сообщение — в результат вызова метода. При каждом вызове он устанавливает связь с сервером, разрывая ее после завер-
2.3. Обращение к удаленным объектам 125
ш ения вызова. Для этого, как уже говорилось, заместитель нуждается в сетевом адресе и конечной точке сервера.
Таким образом, заместитель обладает всей информацией, необходимой для обращения клиента к методу удаленного объекта. В Java заместители сериали-зуются. Другими словами, заместитель можно подвергнуть маршалингу и переслать в виде набора байтов другому процессу, в котором он может быть подвергнут обратной операции (демаршалингу) и использован для обращения к методам удаленного объекта. Косвенным результатом этого является тот факт, что заместитель может быть использован в качестве ссылки на удаленный объект.
Этот подход согласуется с методами интеграции локальных и распределенных приложений в Java. Напомним, что при обращении RMI локальный объект передается путем создания копии, а удаленный — через общесистемную ссылку на объект. Заместитель представляет собой просто-напросто локальный объект. Это означает, что сериализуемый заместитель можно передавать по сети как параметр RMI. В результате появляется возможность использовать заместитель как ссылку на удаленный объект.
В принципе при маршалинге заместителя вся его реализация, то есть его состояние и код, превращаются в последовательность байтов. Маршалинг подобного кода не слишком эффективен и может привести к слишком объемным ссылкам. Поэтому при маршалинге заместителя в Java на самом деле происходит генерация дескриптора реализации, точно определяющего, какие классы необходимы для создания заместителя. Возможно, некоторые из этих классов придется сперва загрузить из удаленного узла. Дескриптор реализации в качестве части ссылки на удаленный объект заменяет передаваемый при маршалинге код. В результате ссылки на удаленные объекты в Java имеют размер порядка нескольких сотен байт.
Такой подход к ссылкам на удаленные объекты отличается высокой гибкостью и представляет собой одну из отличительных особенностей RMI в Java [482]. В частности, это позволяет оптимизировать решение под конкретный объект. Так, рассмотрим удаленный объект, состояние которого изменяется только один раз. Мы можем превратить этот объект в настоящий распределенный объект путем копирования в процессе привязки всего его состояния на клиентскую машину. Каждый раз при обращении клиента к методу он работает с локальной копией. Чтобы гарантировать согласованность данных, каждое обращение проверяет, не изменилось ли состояние объекта на сервере, и при необходимости обновляет локальную копию. Таким же образом методы, изменяющие состояние объекта, передаются на сервер. Разработчик удаленного объекта должен разработать только код, необходимый для клиента, и сделать его динамически подгружаемым при присоединении клиента к объекту.
Возможность передавать заместителя в виде параметра существует только в том случае, если все процессы работают под управлением одной и той же виртуальной машины. Другими словами, каждый процесс работает в одной и той же среде исполнения. Переданный при маршалинге заместитель просто подвергается демаршалингу на приемной стороне, после чего полученный код заместителя можно выполнять. В противоположность этому в DCE, например, передача за-