- PVSM.RU - https://www.pvsm.ru -
Здравствуй!
В ходе работы появилась задача создать несколько RMI реестров, доступных через разные сетевые интерфейсы (локальная сеть и интернет). И к моему удивлению я ничего толком не нашел в сети по этому вопросу. Поэтому разобравшись сам, решил поделиться решением с людьми.
Сервер с двумя сетевыми интерфейсами: локальный и внешний IP-адреса. Интерфейс, используемый клиентом и реализуемый сервером:
public interface Server extends Remote {
public String getMessage() throws RemoteException;
}
Создать два RMI реестра, каждый для своего сетевого интерфейса.
Сразу оговорюсь, что подразумевается, что читатель знаком с основами RMI (если нет, то можно почитать здесь [1], здесь [2] и здесь [3]).При создании реестра, он регистрируется на адрес указанный в параметре java.rmi.server.hostname. Поэтому мы будем устанавливать свое значение hostname перед созданием каждого реестра. Для доступа из интернета важно помнить, RMI использует 2 порта: один для реестра, один для объекта. Т.е. необходимо открыть доступ из интернета к двум портам. Если не указать порт при создании объекта, то он будет создан на анонимном порту, который может быть не доступен из интернета. Итак, действия следующие:
Важно, чтобы в реализации интерфейса, в конструкторе указывался порт.
public final class ServerImpl extends UnicastRemoteObject implements Server {
public ServerImpl(int port) throws RemoteException {
super(port);
}
@Override
public String getMessage() throws RemoteException {
return "hello";
}
}
Registry localRegistry = LocateRegistry.createRegistry(localPort); //создаем реестр для локальной сети
ServerImpl localEngine = new ServerImpl(0); //создаем объект для локальной сети
registry.rebind("rmi://localServer", localEngine);//регистрируем объект в реестре
System.setProperty("java.rmi.server.hostname", "внешний IP-адрес"); //Устанавливаем внешний IP-адрес в java.rmi.server.hostname
Registry registry = LocateRegistry.createRegistry(remotePort1); //создаем реестр для внешней сети на одном из открытых портов
RMIHttpServer engine = new RMIHttpServerImpl(remotePort2); //создаем объект для внешней сети на втором открытом порту
registry.rebind("rmi://remoteServer", engine); //регистрируем объект в реестре
Получаем два RMI реестра, каждый доступен из своего интерфейса. Для дополнительной изоляции реестров можно еще написать свои реализации RMIClientSocketFactory [4] и RMIServerSocketFactory [5], чтобы настроить сокеты для прослушивания только заданных адресов. Но это оставляю для самостоятельного изучения.
Автор: stepanovD
Источник [6]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/java/38102
Ссылки в тексте:
[1] здесь: http://habrahabr.ru/post/74639/
[2] здесь: http://ru.wikipedia.org/wiki/RMI
[3] здесь: http://docs.oracle.com/javase/tutorial/rmi/
[4] RMIClientSocketFactory: http://spec-zone.ru/RU/Java/Docs/7/api/java/rmi/server/RMIClientSocketFactory.html
[5] RMIServerSocketFactory: http://spec-zone.ru/RU/Java/Docs/8/api/java/rmi/server/RMIServerSocketFactory.html
[6] Источник: http://habrahabr.ru/post/185710/
Нажмите здесь для печати.