Сервер через RMI без реестра

У меня есть сервисный объект, к которому можно подключиться через RMI. В настоящее время я делаю это:

Сервер

Registry r = LocateRegistry.createRegistry(1234);
r.bind("server", UnicastRemoteObject.exportObject(remoteServer, 0));

Клиент

RemoteServer s = LocateRegistry.getRegistry("example.com", 1234).lookup("server");

Реестр на сервере используется только для связи с одним объектом сервера. Я подумал, что с тем же успехом мог бы сделать это на сервере:

UnicastRemoteObject.exportObject(remoteServer, 1234);

Но как тогда мне подключиться к объекту сервера с клиента?


person Bart van Heukelom    schedule 01.02.2011    source источник


Ответы (3)


Реестр RMI существует для решения проблемы начальной загрузки RMI, которая просто заключается в том, что вы можете получить удаленную заглушку только через вызов удаленного метода, а для выполнения вызова удаленного метода вам нужна удаленная заглушка. Ссылка на реестр, предоставленная LocateRegistry.getRegistry(), решает эту проблему (и используется внутри Naming.lookup(), если вы используете этот API). [Обратите внимание, что эта заглушка не получена удаленным методом: она синтезируется локально с использованием предоставленного вами хоста:порта. Если они неверны, вы не узнаете, пока не воспользуетесь заглушкой реестра.]

У вас есть несколько вариантов решения проблемы начальной загрузки RMI:

  1. Используйте реестр RMI.

  2. Используйте сервер LDAP через JNDI с поставщиком LDAP.

  3. Используйте UnicastRemoteObject, сериализацию заглушки, полученной при экспорте объекта, и используйте общий файл, или сокет, или сеть кроссвордов, чтобы сделать заглушку доступной для клиентов.

  4. Используйте активацию RMI; сериализуйте заглушку, полученную при регистрации активируемого, и раздайте всем клиентам в файле вместе с клиентским приложением. С точки зрения распространения заглушки это намного проще, чем (3), потому что заглушка остается неизменной на протяжении всего срока службы приложения, тогда как в (3) вы должны перераспределять заглушку при каждом экспорте.

Вы можете видеть, что реестр, безусловно, самый простой вариант. Обратите внимание, что вам нужно использовать его только для решения проблемы с начальной загрузкой. Если у вас есть заглушка, ваши собственные удаленные методы приложения могут возвращать дополнительные объекты: вам не нужно более одного удаленного объекта в реестре. Вы можете рассматривать это как фабрику удаленных объектов.

person user207421    schedule 14.02.2011
comment
Я снова столкнулся с этой проблемой (stackoverflow.com/questions/11399408/), и на этот раз не может использовать реестр. Я мог бы использовать метод 3, но если у клиента есть интерфейс и хост/порт службы, может ли он сам синтезировать заглушку? - person Bart van Heukelom; 09.07.2012
comment
@BartvanHeukelom Теоретически да, на практике нет. Почему вы не можете использовать реестр? - person user207421; 20.07.2012
comment
Отличный намек (3) на то, что это всего лишь сериализованная заглушка, которую нужно каким-то образом доставить клиенту. Никогда не понимал из документов, что это так просто. В настоящее время зоопарк тоже был бы хорошим вариантом. - person Harald; 10.12.2016
comment
Для (3) стоит отметить, что установка системного свойства java.rmi.server.hostname кажется единственным способом получить заглушку, которая может подключаться с одной машины на другую, а не только на локальный хост. - person Harald; 14.12.2016
comment
@Harald Только в том случае, если DNS экспортирующего хоста неправильно настроен или существует проблема с общедоступным/частным IP-адресом. - person user207421; 29.12.2016

Не невозможно, но не очень практично, потому что реестр передает объект-заглушку экспортируемого объекта клиенту (см. http://www.developer.com/print.php/3455311). Если у вас нет другого механизма для этого, вы застрянете. Использование реестра в распределенных системах имеет и другие преимущества, поэтому я бы рекомендовал сохранить его по другим причинам (прозрачность местоположения и т. д.).

person kvista    schedule 01.02.2011
comment
Виста: Это неверно, и это не то, о чем говорит предоставленная вами ссылка. Все, что делает Реестр, это решает проблему начальной загрузки: вы можете получить удаленную заглушку только в результате удаленного метода, для чего вам нужна удаленная заглушка... - person user207421; 13.02.2011
comment
Vista: Нет. Проблема начальной загрузки заключается в предоставлении клиенту начальной заглушки object, как сказано в вашей ссылке. Вы сказали 'класс', что совершенно неверно. Реестр не предоставляет классы. Ваше второе утверждение о «НОВОМ классе-заглушке» для «НОВОГО экземпляра объекта» также не имеет никакого смысла. - person user207421; 15.02.2011
comment
@EJB: Если проблема заключается в использовании класса и объекта, я согласен с вами и исправил это. Основная часть моей точки зрения заключается в том, откуда берется заглушка, и в необходимости реестра, что, несомненно, было сутью вопроса. Кстати, я не могу отредактировать свой комментарий выше, поэтому я его удаляю. - person kvista; 15.02.2011

Клиент использует URL-адрес rmi, например rmi://localhost:2020/server.

см. https://stackoverflow.com/a/61210297/503025

person weberjn    schedule 14.04.2020