- •JAVA-ТЕХНОЛОГИЯ
- •Remote Method Invocation
- •Недостатки RPC
- •Архитектура RMI
- •Схема RMI
- •Пример
- •Серверная часть.
- •Compute.java
- •Task.java
- •Реализация удаленного интерфейса
- •ComputeImpl.java
- •ComputeServer.java
- •ComputeServer.java
- •UnicastRemoteObject
- •UnicastRemoteObject
- •UnicastRemoteObject
- •Регистрация удаленных объектов
- •RMI registry
- •RMI-реестр
- •RMI-реестр
- •Менеджер безопасности
- •Передача объектов в RMI
- •Клиентская часть
- •Клиентская часть
- •ComputeClient.java
- •ComputeService
- •ComputeClient
- •Заглушки
- •Скелетные схемы
- •Компиляция и выполнение
- •Запуск RMI-клиента
ComputeImpl.java
import java.rmi.*; import java.rmi.server.*;
public class ComputeImpl
extends UnicastRemoteObject implements Compute {
public ComputeImpl() throws RemoteException { super();
}
public Object executeTask( Task t) { return t.execute();
}
}
(С) Сафонов В.О. 2013
ComputeServer.java
import java.rmi.*;
import java.rmi.registry.*; public class ComputeServer {
public ComputeServer() {
System.setSecurityManager(new
RMISecurityManager());
String name = “ComputeService"; try {
Compute compImpl = new ComputeImpl(); LocateRegistry.createRegistry(1099);
Naming.rebind(name, compImpl); System.out.println("ComputeServer bound");
(С) Сафонов В.О. 2013
ComputeServer.java
} catch (Exception e) {
System.err.println
("ComputeEngine exception: " + e.getMessage());
e.printStackTrace();
}
}
public static void main(String[] args) { new ComputeServer();
}
}
(С) Сафонов В.О. 2013
UnicastRemoteObject
UnicastRemoteObject - удобный класс, определенный в RMI API, который может использоваться как
суперкласс для реализаций удаленного объекта.
UnicastRemoteObject включает в себя конструкторы и статические методы, используемые для экспорта (exportObject()) удаленных объектов.
Конструкторы и методы UnicastRemoteObject бросают исключение RemoteException, поэтому все его подклассы должны определять конструкторы, которые также генерируют это исключение.
(С)Сафонов В.О. 2013
UnicastRemoteObject
Экспортированный объект становится доступным для прослушивания поступающих от клиентов запросов на порту по умолчанию
Можно указать определенный порт для приема запросов : exportObject( Remote obj, int port) . При этом
в URL удаленного объекта необходимо указать этот порт : //host:port/objectname .
Замечание: порт по умолчанию – 1099.
Расширение UnicastRemoteObject класса
ComputeEngine может быть использовано для создания простого удаленного объекта, который поддерживает однонаправленную удаленную связь и который использует принимаемую по умолчанию
сокетную транспортную службу RMI для |
|
коммуникаций. |
(С) Сафонов В.О. 2013 |
|
|
UnicastRemoteObject
Класс, не расширяющий UnicastRemoteObject, может использовать свой метод exportObject() для присоединения к RMI.
Можно выбрать расширение из класса JDK java.rmi.activation.Activatable (используемого для конструирования удаленных объектов, которые могут выполняться по требованию) .
В обоих случаях необходимо экспортировать объект явным вызовом из конструктора удаленного объекта (или из другого метода инициализации) .
(С)Сафонов В.О. 2013
Регистрация удаленных объектов
Вызов статического метода Naming.bind( ) требует, чтобы регистрация была запущена отдельным процессом на компьютере сервера. Имя сервера регистрации - rmiregistry.
Для Win32 используется команда start rmiregistry для запуска сервера в фоновом режиме.
Замечание: Для UNIX аналогичная команда: rmiregistry &
Если вызвать rmiregistry, как показано выше, без аргументов, будет использован порт по умолчанию 1099. Для использования другого порта добавляют аргумент – номер порта.
Пример: rmiregistry 2010
rmiregistry 2010 & (для UNIX)
(С) Сафонов В.О. 2013
RMI registry
Не обязательно запускать rmiregistry как внешний процесс. Если Вы знаете, что только Ваше приложение использует регистрацию, Вы можете загрузить ее внутри вашей программы с помощью строки:
LocateRegistry.createRegistry( 2010 )
Это эквивалентно запуску rmiregistry 2010 из командной строки, но часто этот способ является более подходящим при разработке RMI-кода, так как это снижает число необходимых действий при запуске и остановке регистрации.
Пока rmiregistry остается запущенным, и Вы не вызовете Naming.unbind( ) на вашей машине, объект будет сохраняться там
Замечание: При запуске rmiregistry переменная
CLASSPATH должна содержать ссылку на директорию, где находятся файлы сервера.
(С)Сафонов В.О. 2013
RMI-реестр
java.rmi.Naming – API для связывания, регистрации и поиска удаленных объектов в реестре.
Метод rebind() класса Naming (из java.rmi) обновляет RMI-реестр(сервис имен удаленных объектов) на машине сервера.
Сервер вызывает реестр для того, чтобы связать имя с удаленным объектом. Клиент ищет удаленный объект по его имени в реестре сервера, а затем вызывает его метод.
Замечание: Программисты чаще используют rebind, поскольку он гарантирует, что если объект уже был зарегистрирован под заданным именем, новый удаленный объект заменит ранее зарегистрированный объект. Это может быть важно, если регистрируется новая версия удаленного объекта.
(С)Сафонов В.О. 2013
RMI-реестр
Вызов rebind() может приводить к генерации RemoteException, так что должно обрабатываться данное исключение (в try-catch блоке)
Если имя уже зарегистрировано и вызывается метод bind(), будет брошено AlreadyBoundException
Нет необходимости иметь поток, ожидающий в течение всего времени жизни сервера. Пока на другой виртуальной машине имеется ссылка на объект ComputeImpl, объект ComputeImpl не будет уничтожен или отправлен в "мусор".
(С)Сафонов В.О. 2013
