63315

Удаленный интерфейс. Remote Method Invocation

Лекция

Информатика, кибернетика и программирование

Традиционный подход к выполнению на удаленной машине сбивал с толку, а также был утомителен и подвержен ошибкам при реализации. Лучший способ представить эту проблему – это думать, что какой-то объект живет на другой машине, и что вы можете посылать сообщения удаленному объекту и получать результат, будто бы объект живет на вашей машине.

Русский

2014-06-19

66.5 KB

1 чел.

  1.  Remote Method Invocation    

Традиционный подход к выполнению на удаленной машине сбивал с толку, а также был утомителен и подвержен ошибкам при реализации. Лучший способ представить эту проблему – это думать, что какой-то объект живет на другой машине, и что вы можете посылать сообщения удаленному объекту и получать результат, будто бы объект живет на вашей машине. Говоря простым языком, это в точности то, что позволяет делать Удаленный вызов методов  (Remote Method Invocation - RMI) Java.

Удаленный интерфейс

RMI большей частью использует интерфейсы. При создании своего удаленного объекта вы скрываете его низкоуровневую реализацию, передавая ссылку на его интерфейс. Таким образом, когда удаленный клиент получает ссылку на объект, на самом деле он получает ссылку на интерфейс, который по некоторой причине оказывается подсоединенным к локальному коду – “заглушке”, который и производит переговоры по сети. Но вы не заботитесь об этом, вы просто посылаете сообщения через ссылку на  интерфейс.    

Когда вы создаете удаленный  интерфейс, вы должны следовать следующей инструкции:

  1.  Удаленный  интерфейс должен быть открытым – public (он не должен иметь “доступ на уровне пакета”, так же он не может быть “дружественным”). В противном случае клиенты будут получать ошибку при попытке загрузки удаленного объекта, реализующего удаленный  интерфейс.
  2.  Удаленный  интерфейс должен расширять интерфейс, java.rmi.Remote.
  3.  Каждый метод удаленного интерфейса должен объявлять java.rmi.              RemoteException в своем предложении throws вдобавок к любым исключениям, специфичным для вашего приложения.
  4.  Удаленный объект, передаваемый как аргумент или возвращаемое значение (прямо или косвенно как объект – член локального объекта), должен быть объявлен как удаленный  интерфейс, а не как класс с реализацией.
Ниже приведен простой удаленный  интерфейс, представляющий сервис точного времени:
import java.rmi.* ;
interface PerfectTimeI extends Remote {
        long  getPerfectTime () throws RemoteException;
Он выглядит как любой другой интерфейс, за исключением того, что расширяет  другой интерфейс Remote и все его методы выбрасывают RemoteException. Помните, что интерфейс и все его методы автоматически становятся public.
 
Реализация удаленного  интерфейса
Сервер должен содержать класс, который расширяет UnicastRemoteObject и реализует удаленный  интерфейс. Этот класс также может иметь другие методы, но для клиента доступны только методы удаленного  интерфейса, так как клиент получает ссылку только на удаленный  интерфейс, а не на класс, который его реализует.
Вы должны явно определить конструктор для удаленного объекта, даже если вы определяете конструктор по умолчанию, который вызывает конструктор базового класса. Вы должны написать его, так как он должен выбрасывать RemoteException.
Ниже приведена реализация удаленного интерфейса PerfectTimeI:
import  java.rmi.* ;
import  java.rmi.server.* ;
import  java.rmi.registry.* ;
import  java.rmi.net.* ;
public class PerfectTime extends UnicastRemoteObject implements PerfectTimeI {
         // Реализация интерфейса:
        public long getPerfectTime () throws  RemoteException {
                 return System.currentTimeMillis ();
        }
        //  Должна быть реализация конструктора
        //  для выбрасывания RemoteException :
      public PerfectTime () throw RemoteException {
                // super (); // вызывается автоматически
      }
      //  Регистрация для обслуживания RMI. Выбрасывает 
      //  исключения на консоль.
      Public static void main (String [] args) throws  Exception {
               System.setSecurityManager (new RMISecurityManager ());
               PerfectTime pt = new PerfectTime ();
               Naming.bind (“//Ready to do time”);
      }
 }
В   этом примере main () обрабатывет все установки сервера. Когда вы обслуживаете RMI объект, в определенном месте вашей программы вы должны:
  1.  Создать и установить менеджер безопасности, поддерживающий сервисы RMI. Как часть Java пакета, для RMI поддерживается только RMISecurityManager.
  2.  Создать один или несколько экземпляров удаленного объекта. Здесь вы видите создание объекта PerfectTime.
  3.  Зарегистрировать не менее одного удаленного объекта в реестре удаленных объектов RMI, чтобы в последствии ими можно было пользоваться. Этот удаленный объект может иметь методы, которые производят ссылки на другие удаленные объекты. Их также можно зарегистрировать в реестре, чтобы клиенту не пришлось обращаться к нему много раз.
Установка реестра
В рассмотренном примере вызывался статический метод Naming.bind(). Однако для вызова этого метода требуется, чтобы реестр был запущен отдельным процессом на вашем компьютере. Имя сервера реестра – это rmiregistry, и для запуска под 32-битной Windows необходимо выполнить следующую команду:
start rmiregistry
              port 1099
для запуска его в качестве фонового процесса или  start rmiregistry 2005
Как и многие другие сетевые программы, сервер rmiregistry располагается по IP адресу машины, с которой его установили, но он также должен прослушивать порт под определенным порядковым номером. Если вы вызовите rmiregistry как показано выше, без аргументов, будет использован порт по умолчанию 1099. Если вы хотите использовать другой порт, вы добавляете аргумент в командную строку, указывающий порт. Следующий пример устанавливает порт 2005, поэтому rmiregistry под управлением 32-битной Windows должен запускаться так:
start rmiregistry 2005
Информацию о порте также необходимо передать в метод bind(), наряду с IP адресом машины, где располагается сервер реестра. Но при попытке использовать локальный IP-адрес, как это делается при тестировании сетевых программ, возникает досадная проблема. В JDK 1.1.1 существовала пара таких проблем:
  1.  Локальный IP-адрес localhost не работает с библиотекой RMI. Поэтому для экспериментов с RMI на одной машине вы должны использовать настоящее имя машины.
  2.  Библиотека RMI не станет функционировать, пока у вас не будет настоящего TCP/IP соединения, даже если все ваши компоненты просто общаются друг с другом на одной машине. Это значит, что вы должны соединиться с вашим Internet-провайдером до того, как попробуете запустить программу, иначе возникнут странные сообщения об ошибках.
Если учесть все это, команда bind () примет вид:
Naming.bind (“//peppy: 2005/PerfectTime”, pt);

Если вы используете порт по умолчанию 1099, вам не нужно указывать порт, так что вы можете просто сказать:

Naming.bind("//peppy/PerfectTime", pt);

Вы можете выполнить локальную проверку оставив в покое IP адрес, а использовать только идентификатор:

Naming.bind("PerfectTime", pt);

Имя сервиса здесь произвольно. В данном случае PerfectTime выбрано просто как имя класса, но вы можете назвать так, как захотите. Важно, чтобы это было уникальное имя регистрации, чтобы клиент знал имя, когда будет искать определенный удаленный объект. Если имя уже зарегистрировано, вы получите AlreadyBoundException. Чтобы предотвратить это, вы всегда можете использовать rebind () вместо bind (), так как rebind () либо добавляет новый элемент, либо заменяет уже существующий.

Даже после завершения работы main(), ваш объект остается существовать в реестре, ожидая, что придет клиент и выполнит запрос. Пока rmiregistry остается запущенным, и вы не вызовите Naming, unbind () на вашей машине, объект будет оставаться там. По этой причине, при отладке вашего кода необходимо выгружать rmiregistry и перезапускать его, когда скомпилируете новую версию вашего удаленного объекта.

Вам не обязательно запускать rmiregistry как внешний процесс. Если вы знаете, что только ваше приложение использует регистрацию, вы можете загрузить ее внутри вашей программы с помощью строки:

 LocateRegistry.createRegistry(2005);

Как и раньше, 2005 - это номер порта, который использовался в этом примере. Это эквивалентно запуску rmiregistry 2005 из командной строки, но часто этот способ является более удобным при разработке RMI-приложений, так как это снижает число необходимых действий при запуске и остановке реестра. После того, как вы выполните этот код, вы можете вызвать Naming. bind (), как и ранее.

Создание заглушек и каркасов

Если вы откомпилируете и запустили PerfectTime . Java, оно не будет работать, даже если вы правильно запустили rmiregistry. Это происходит потому, что основного каркаса библиотеки RMI еще не создано. Вы должны сначала создать заглушки и каркасы, которые обеспечат работу сетевого соединения и позволят вам делать вид, что удаленный объект - это просто локальный объект на вашей машине.

То, что происходит за сценой - очень сложно. Любой объект, который вы передаете или получаете из удаленного объекта, должен реализовывать(1тр!етеп1) Serializable (если вы хотите передавать удаленные ссылки вместо целых объектов, аргументы объектов могут реализовывать Remote), так что вы можете представить, как заглушки и каркасы автоматически выполняют сериализацию и десериализацию во время | «упаковки» параметров методов и возвращаемых результатов. К счастью, вам не нужно знать всего этого, но вы должны создавать заглушки и каркасы. Это простой процесс: вы вызываете инструмент rmic для вашего откомпилированного кода, а он создает необходимые файлы. Так что от вас требуется включить еще один шаг в процесс компиляции.

PerfectTime.java находится в пакете clS.rmi:

rmic c!5.rmi.PerfectTime

Вам не нужно быть в директории, содержащей PerfectTime. class, когда вы исполняете эту команду, но результат будет помещен в текущий директорий (из которого вы запустили команду).

Когда выполнение программы rmic завершится успешно, вы найдете два новых класса в директории:

PerfectTime_Stub.class

PerfectTime_Skel.class

соответствующих заглушке и каркасу. Теперь вы готовы запустить общение клиента с сервером.

Использование удаленных объектов

Главная цель RMI состоит в упрощении использования удаленных объектов. Вы должны сделать только самую важную вещь в вашей клиентской программе: это поиск и получение удаленного интерфейса с сервера. Во всем остальном - это обычное программирование на Java: посылка сообщений объекту. Ниже приведена программа, использующая PerfectTime:

import java.rmi.*;

import Java . rmi . registry .*;

public class DisplayPerfectTime {

           public static void main (String [] args) throws Exception {

           System.setSecurityManager (new RMISecurityManager ()) ;

             PerfectTimel t = (PerfectTimel ) Naming. lookup (

     "//peppy: 2005/PerfectTime") ;

for(int i = 0; i < 10; i++)

                  System. out . println ( "Perfect time = " +

                        t . getPerf ectTime (

                }

        } ;

Использованный идентификатор совпадает с тем, что использовался при регистрации объекта в реестре помощью Naming, а первая часть представляет URL и номер порта. Так как вы используете URL, вы можете также указать любую машину в Internet.

То, что возвращается из Naming, lookup () должно быть преобразовано к удаленному интерфейсу, а не к классу. Если вы будите использовать класс, вы получите исключение.

Вы можете видеть, что вызов удаленного метода

t.getPerfectTime ( )

ничем не отличается от вызова метода любого локального объекта. Как только вы получаете ссылку на удаленный объект, программирование с ним ничем не отличается от программирования с локальными объектами (за одним исключением: удаленные методы способны возбуждать исключение RemoteException.


 

А также другие работы, которые могут Вас заинтересовать

65696. Математичні моделі оцінювання стратегічного потенціалу підприємства та прийняття рішень щодо його підвищення 329 KB
  Велика кількість існуючих моделей та методологічних підходів до визначення СПП дає можливість керівникам здійснити вибір засобів прийняття рішення щодо подальшого розвитку підприємства проте жоден з існуючих підходів не є достатньо ефективним як за критерієм повноти аналізованої інформації...
65697. УДОСКОНАЛЕННЯ ВИЗНАЧЕННЯ СТРАТЕГІЇ ПІДПРИЄМСТВА В УМОВАХ КРИЗИ НА ОСНОВІ ЗБАЛАНСОВАНОЇ СИСТЕМИ ПОКАЗНИКІВ 1.13 MB
  Сучасна фінансова, політична та економічна нестабільність в Україні, головними ознаками якої є високе боргове навантаження на вітчизняну економіку, негативні тенденції на грошово-кредитному ринку, ринку праці та у промисловості – провідній галузі вітчизняної економіки...
65698. Діяльність Служби безпеки ОУН(б) на території Волині та Полісся (1946 − 1951 рр.) 159.5 KB
  Обєктивне дослідження історії ОУНб є неможливим без скрупульозного аналізу діяльності її регіональних складових. Метою роботи є встановлення впливу СБ ОУНб на розвиток українського національно-визвольного руху на Волині та Поліссі в період поступового згасання збройної антирадянської боротьби.
65699. ПРАВОВЕ РЕГУЛЮВАННЯ ВІДШКОДУВАННЯ ПОДАТКУ НА ДОДАНУ ВАРТІСТЬ В УКРАЇНІ 216.5 KB
  Хоча останній і запровадив спрощення адміністративних процедур автоматичне відшкодування зменшення податкового навантаження стимулював інноваційно-інвестиційну діяльність урегулював адміністрування податків взаємовідносини з контролюючими органами окремі проблеми залишились актуальними.
65700. АДМІНІСТРАТИВНО-ПРАВОВИЙ СТАТУС ПРАЦІВНИКА ДЕРЖАВНОЇ КОНТРОЛЬНО-РЕВІЗІЙНОЇ СЛУЖБИ УКРАЇНИ 186.5 KB
  Працівники ДКРСУ виконують завдання держави спрямовані на забезпечення фінансової діяльності держави. З метою забезпечення успішної реалізації цих завдань суттєвого поліпшення потребують не лише форми і методи діяльності ДКРСУ але й якісний підхід до визначення адміністративно-правового статусу працівника ДКРСУ.
65701. СТАНОВЛЕННЯ І РОЗВИТОК ПРИВАТНОЇ ОСВІТИ НА ВОЛИНІ (ДРУГА ПОЛОВИНА ХІХ – ПОЧАТОК ХХ СТ.) 205 KB
  Робота виконана в Житомирському державному університеті імені Івана Франка Міністерство освіти і науки молоді та спорту України. В умовах розвитку України в європейському та світовому контекстах сучасних соціальноекономічних змін особливої ваги набувають процеси оптимізації та вдосконалення...
65702. ОСОБЛИВОСТІ ЦИВІЛЬНО-ПРАВОВОГО СТАТУСУ ГОСПОДАРСЬКОГО ТОВАРИСТВА ОДНІЄЇ ОСОБИ (НА ПРИКЛАДІ ЗАКОНОДАВСТВА УКРАЇНИ ТА ФРН) 157.5 KB
  У теперішній час формування інституту господарського товариства однієї особи у рамках національного законодавства України нерозривно повязане із розвитком та вдосконаленням його у світовій практиці враховуючи орієнтацію національної економіки на глобалізацію...
65703. ГРОШОВО-КРЕДИТНЕ РЕГУЛЮВАННЯ ТА ЙОГО РОЛЬ У ЗАБЕЗПЕЧЕННІ РІВНОВАГИ ДОХОДУ ТА ПЛАТІЖНОГО БАЛАНСУ ДЕРЖАВИ 362.5 KB
  Фінансові системи країн ЦСЄ та колишнього Радянського Союзу істотно відрізняються обраними режимами грошово-кредитної політики та рівнем монетизації, проте динаміка монетарних показників залишається як універсальним індикатором відхилень від рівноваги доходу і платіжного балансу...
65704. Маркетинг-логістичне забезпечення діяльності машинобудівних підприємств 443 KB
  Тенденції щодо зростання рівня конкуренції на світових і національних ринках загострюють проблему пошуку товаровиробниками нових підходів щодо забезпечення ефективності виробничо-збутової діяльності промислового підприємства.