Java RMI, как сервер должен управлять аварийным завершением работы клиента, когда он не вызывает какой-либо клиентский метод? - PullRequest
0 голосов
/ 02 апреля 2012

Я разрабатываю приложение с использованием Java RMI, которое позволяет клиентам регистрировать темы, которые они хотят прослушать (ноль или более), и темы (ноль или одна), о которых они хотят говорить. Существует центральный сервер, который предлагает услугу регистрации. Общение клиентов обходится без сервера, за исключением начальной регистрации ListenerCallback или SpeakerCallback. Клиенты и сервер работают по шаблону Observer.

Интерфейсы обратного вызова:

public interface ListenerCallback extends Remote{

void notify(String topic, String msg) throws RemoteException;

} 

public interface SpeakerCallback extends Remote{

Unregister accept(ListenerCallback listenerCallback) throws RemoteException;

}

Фрагмент метода регистрации на сервере, и говорящий, и слушатель являются удаленными ссылками:

for (SpeakerCallback speaker : registeredSpeakers){
    try {
        speaker.accept(listener);
    } catch (RemoteException e){
        //TODO should I unregister speaker?
    }
}

Как написано выше в // TODO, я полагаю, что мне следует отменить регистрацию оратора в реестрах моих приложений, поскольку, насколько я знаю, RemoteException указывает на разрыв соединения с клиентом.

Проблема, с которой я сталкиваюсь, заключается в том, как мне справиться с ненормальным завершением работы клиента, который только слушает какую-то тему, но ни о чем не говорит. Сервер хранит их в реестрах приложений, но не может определить, действительны ли они по-прежнему, поскольку он не вызывает метод notify ().

Должен ли я добавить в интерфейс ListenerCallback какой-то фиктивный метод только для того, чтобы определить, доступен ли клиент по-прежнему?

Или я должен внедрить протокол, который позволил бы клиентам, которые говорят (метод call notify ()) об определенном сервере тем, уведомлять о том, что некоторые прослушивающие клиенты больше не доступны?

Ответы [ 2 ]

1 голос
/ 02 апреля 2012

Это задание для шаблона удаленного сеанса. Каждый клиент выполняет шаг входа в систему, который выделяет и возвращает новый удаленный объект, который действительно является объектом сеанса, который, в свою очередь:

  1. имеет метод logout(), который не экспортирует объект

  2. предоставляет другие API, необходимые клиенту, и

  3. реализует Unreferenced, при этом метод unreferenced() вызывает logout().

Так что, если клиент либо позвонит logout(), либо умрет, объект исчезнет; и любые побочные действия должны произойти в методе logout().

0 голосов
/ 02 апреля 2012

Если вы получаете remoteException, это не означает, что клиент не работает, вам придется проверить подтипы remoteEception, такие как ConnectException и т. Д., Которые сообщают, что больше нет конечной точки, только тогда вы можете отменить регистрацию клиента.

Для проверки, живы ли клиенты, вы можете внедрить некоторый фиктивный API на стороне клиента и использовать его для проверки связи с клиентом в задаче таймера.Вы можете оптимизировать этот интервал проверки связи в зависимости от серьезности устаревания регистрации клиента.

...