RMI для нескольких сетевых интерфейсов

от автора

Здравствуй, Хабр!
В ходе работы появилась задача создать несколько RMI реестров, доступных через разные сетевые интерфейсы (локальная сеть и интернет). И к моему удивлению я ничего толком не нашел в сети по этому вопросу. Поэтому разобравшись сам, решил поделиться решением с людьми.

Дано

Сервер с двумя сетевыми интерфейсами: локальный и внешний IP-адреса. Интерфейс, используемый клиентом и реализуемый сервером:

public interface Server extends Remote {     public String getMessage() throws RemoteException; } 

Задача

Создать два RMI реестра, каждый для своего сетевого интерфейса.

Решение

Сразу оговорюсь, что подразумевается, что читатель знаком с основами RMI (если нет, то можно почитать здесь, здесь и здесь).При создании реестра, он регистрируется на адрес указанный в параметре java.rmi.server.hostname. Поэтому мы будем устанавливать свое значение hostname перед созданием каждого реестра. Для доступа из интернета важно помнить, RMI использует 2 порта: один для реестра, один для объекта. Т.е. необходимо открыть доступ из интернета к двум портам. Если не указать порт при создании объекта, то он будет создан на анонимном порту, который может быть не доступен из интернета. Итак, действия следующие:

  1. Пишем реализацию интерфейса с указанием порта;
  2. Создаем реестр для локальной сети;
  3. Создаем объект и регистрируем его в реестр;
  4. Передаем в java.rmi.server.hostname значение внешнего IP-адреса;
  5. Создаем реестр для внешней сети на одном из открытых портов;
  6. Создаем объект для внешней сети на втором из открытых портов и регистрируем его в реестре;
  7. Profit.
Реализация интерфейса

Важно, чтобы в реализации интерфейса, в конструкторе указывался порт.

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 и RMIServerSocketFactory, чтобы настроить сокеты для прослушивания только заданных адресов. Но это оставляю для самостоятельного изучения.

ссылка на оригинал статьи http://habrahabr.ru/post/185710/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *