Я работал над внутренним учебным пособием по Java RMI, после просмотра учебного пособия по Sun RMI, и я только вроде понимаю, что происходит. Есть несколько вещей, которые кажутся мне странными, и я хотел бы узнать, что на самом деле происходит, прежде чем дать отзыв об учебнике.
В этом руководстве я напишу следующие компоненты:
- Интерфейс, скажем RemoteInterface, с методами, к которым мы хотим получить удаленный доступ.
- Класс, скажем RemoteServer, реализующий RemoteInterface, который в своем конструкторе:
- Создает объект реестра, вызывая
LocateRegistry.createRegistry(PORTNO)
- Создает объект-заглушку RemoteInterface, вызывая
UnicastRemoteObject.exportObject(this, PORTNO)
и приводя результат.
- Связывает заглушку с реестром с помощью
registry.rebind(BINDNAME, stub)
- Класс, скажем, ServerDemo, у которого есть метод main, который просто создает экземпляр RemoteServer.
- Клиентский класс, который вызывает сервер, используя BINDNAME, и все работает нормально.
Сначала я заметил, что:
- Сервер продолжает работать после завершения основного метода. Я должен прекратить это явно. На мой взгляд, он должен просто создать объект и затем завершиться, но программа не завершается, и клиент все еще может подключиться.
- Если я вызываю
registry.unbind(BINDNAME)
в конструкторе RemoteServer, клиент перестает работать, но сервер по-прежнему не завершает работу.
- Если я вызову
UnicastRemoteObject.unexportObject(this, true);
в конструкторе RemoteServer, сервер немедленно завершит работу.
Я хотел бы знать, почему это происходит - хотя если бы это было не так, сервер был бы бесполезен, поскольку он просто немедленно завершил бы работу. (В своем отзыве я предлагаю предложить методы привязки и отмены привязки RemoteServer для вызова ServerDemo, вместо того чтобы выполнять все привязки в конструкторе, никогда не отменять привязку и полагаться на работу сервера по какой-то причине - но сначала я хотелось бы понять, почему это происходит.)
Во-вторых, я заметил, что могу позвонить UnicastRemoteObject.exportObject(this, PORTNO)
до , позвонив LocateRegistry.createRegistry(PORTNO)
, и все по-прежнему работает. Я предполагал, что реестр должен быть настроен, прежде чем мы сможем экспортировать в него, но, очевидно, он не работает так, как я думал.
Мне бы хотелось немного узнать о том, как на самом деле работает exportObject. (Я полагаю, это связано с предыдущим пунктом - почему использование объекта exprted останавливает выполнение программы?)
Кроме того, если я экспортирую и связываю заглушку в одном методе, готовую к извлечению и отмене привязки в другом методе, я хотел бы знать , нужно ли мне явно сохранять ссылку на заглушку в между. (Только BINDNAME необходим для отмены привязки.) Один из моих коллег сообщил о проблемах с GC, и хотя я сам их не заметил, я не могу исключить их, потому что я не совсем понимаю, что происходит.