Как клиент RMI может видеть и регистрировать все динамические удаленные объекты в реестре?

У меня есть требование, чтобы клиент RMI зарегистрировал все удаленные объекты в удаленном реестре RMI.

Первый вопрос: я знаю, что существует метод register.list(), который возвращает все имена объектов. Однако как мне получить объекты именно того типа, который мне нужен (реализуя интерфейс, который я хочу), если предположить, что есть и другие типы зарегистрированных объектов. Должен ли я пройти по именам и использовать оператор try/catch, пытаясь создать экземпляр каждого удаленного объекта?

Второй вопрос, как клиент может быть замечен, если регистрируется новый объект? По моему требованию серверы будут динамически регистрировать новые объекты в реестре, а клиенту необходимо обновляться и получать доступ к новым объектам раньше. Должен ли я просто использовать поток для периодического перечисления всех имен, чтобы узнать новые объекты?

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


person Gordon Liang    schedule 05.10.2015    source источник


Ответы (1)


Как клиент RMI может видеть и регистрировать все динамические удаленные объекты в реестре?

Позвонив Naming.list() или Registry.list().

У меня есть требование, чтобы клиент RMI зарегистрировал все удаленные объекты в удаленном реестре RMI.

См. выше.

Как мне получить объекты именно того типа, который мне нужен (реализуя интерфейс, который я хочу), если предположить, что есть и другие типы зарегистрированных объектов? Должен ли я пройти по именам и использовать оператор try/catch, пытаясь создать экземпляр каждого удаленного объекта?

Просто просмотрите имена, возвращаемые list(); lookup() каждый; и используйте instanceof, чтобы определить, относится ли он к нужному вам типу. Если в реестре есть заглушки, для которых у вас нет всех необходимых классов на клиенте, вам нужно поймать ClassNotFoundException. Простой способ сделать все это за меньшее количество шагов — использовать JNDI listBindings().

Второй вопрос, как клиент может быть замечен, если регистрируется новый объект?

Это невозможно. Для реестра RMI не определена система прослушивания. Клиент должен будет провести опрос.

По моему требованию серверы будут динамически регистрировать новые объекты в реестре, а клиенту необходимо обновляться и получать доступ к новым объектам раньше. Должен ли я просто использовать поток для периодического перечисления всех имен, чтобы узнать новые объекты?

да.

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

Вам будет сложно это организовать, так как вы можете звонить bind() и друзьям только с того же хоста, что и реестр. Вам нужно будет организовать несколько промежуточных удаленных объектов для регистрации каждого нелокального узла.

Я знаю, если они из одного и того же узла, возможно, я могу использовать функцию обратного вызова, вызываемую из одного из экземпляров удаленного объекта.

Быть из одного узла не является для этого предварительным условием. Вы можете выполнять обратные вызовы RMI в любой топологии, где брандмауэры не мешают.

person user207421    schedule 05.10.2015
comment
Еще проще без ClassCastExceptions использовать метод javax.naming.Context.list(), который возвращает перечисление пар `{name, class-name} без извлечения объектов. - person user207421; 05.10.2015
comment
Когда я попытался изучить использование javax.naming, я обнаружил следующий интерфейс: javax.naming.event.NamingListener. Судя по описанию, его можно использовать для прослушивания событий изменения имени, например добавления имени и т. д. Применимо ли это к моему требованию? - person Gordon Liang; 11.10.2015
comment
Я пробовал javax.naming.Context.list(), но не знаю, почему getClassName() всегда возвращает java.lang.object, а не фактическое имя рабочего класса... И если я попробовал listBindings(), это всегда возвращайте com.sun.proxy.$Proxy#, где # — число.... - person Gordon Liang; 11.10.2015
comment
Я закончил с решением try/catch, чтобы поймать ClassCastException и игнорировать его. Это не выглядит хорошим решением, но я не знаю, почему и Context.list(), и Context.listBindings() не возвращают настоящее имя класса. Даже если я попробовал метод object.getClass().getName(), он возвращает имя $Proxy. Я думаю, что опубликую еще один вопрос подробно об этом и не стесняюсь комментировать это. В любом случае, спасибо! - person Gordon Liang; 11.10.2015
comment
Реестр RMI не поддерживает NamingListeners. com.sun.proxy.$Proxy# это настоящее имя класса: имя класса динамического прокси. - person user207421; 21.11.2016