简体   繁体   English

Java RMI,当服务器不调用任何客户端方法时,服务器应如何管理客户端异常关闭?

[英]Java RMI, how should server manage abnormal client shutdown, when it doesn't call any client method?

I'm developing a application using Java RMI which enable clients to register topics they want to listen (zero or more) and topic (zero or one) they want to speak about. 我正在使用Java RMI开发一个应用程序,该应用程序使客户端能够注册他们想听的主题(零个或多个)和他们想谈论的主题(零个或一个)。 There is a central server which offers registration service. 有一个提供注册服务的中央服务器。 The communication of clients avoids server with the exception of initial registering of ListenerCallback or SpeakerCallback. 客户端的通信避免了服务器,但初始注册了ListenerCallback或SpeakerCallback。 Clients and server work according to Observer pattern. 客户端和服务器根据观察者模式工作。

Callback interfaces: 回调接口:

public interface ListenerCallback extends Remote{

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

} 

public interface SpeakerCallback extends Remote{

Unregister accept(ListenerCallback listenerCallback) throws RemoteException;

}

Fragment of registration method on server, both speaker and listener are remote references: 服务器上注册方法的片段,说话者和监听者都是远程引用:

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

As written above in //TODO, I suppose I should unregister speaker from my application registries, because as far as I know RemoteException indicates that the connection with client is broken. 如上面在// TODO中所述,我想我应该从应用程序注册表中注销发言人,因为据我所知,RemoteException表示与客户端的连接已断开。

The problem I'm struggling with is how should I manage abnormal client shutdown that only listen to some topic but speak about none. 我正在苦苦挣扎的问题是我应该如何处理异常的客户端关闭,这种关闭只听某个话题,却什么也没说。 The server holds them in application registries, but has no way to determine whether they are still valid, because it doesn't call its notify() method. 服务器将它们保存在应用程序注册表中,但是无法确定它们是否仍然有效,因为它未调用其notify()方法。

Shoud I add some bogus method to ListenerCallback interface just for trying to determine whether client is still reachable? 我应该向ListenerCallback接口添加一些虚假方法,只是为了尝试确定客户端是否仍然可以访问?

Or should I implemented a protocol which would enable clients who speak about (these call notify() method) a certain topic notify server that some listening clients are no more available? 还是我应该实施一个协议,使谈论(这些调用notify()方法)某个主题的客户端通知服务器某些监听客户端不再可用?

This is a job for the Remote Session pattern. 这是“远程会话”模式的工作。 Every client does a login step, which allocates and returns a new remote object which is really a session object, which in turn: 每个客户端都执行登录步骤,该步骤分配并返回一个新的远程对象,该对象实际上是一个会话对象,该对象依次是:

  1. has a logout() method, which unexports the object 有一个logout()方法,该方法取消导出对象

  2. provides the other APIs the client needs, and 提供客户端需要的其他API,以及

  3. implements Unreferenced , with the unreferenced() method calling logout() . 通过调用logout()unreferenced()方法实现Unreferenced

So if the client either calls logout() or dies the object will disappear; 因此,如果客户端调用logout()或死亡,则该对象将消失; and whatever collateral actions need to happen can all happen in the logout() method. 任何需要采取的附带措施都可以在logout()方法中进行。

If you get a remoteException, that does not mean the client is down, you will have to check the sub types of remoteEception like ConnectException etc which inform that there is no endpoint anymore, only then you can unregister the client. 如果收到remoteException,这并不意味着客户端已关闭,则必须检查remoteEception的子类型(例如ConnectException等),该子类型通知不再存在端点,只有这样才能注销客户端。

For checking if the clients are alive you can implement some dummy API on the client side and use it for pinging the client in a timer task. 为了检查客户端是否还活着,您可以在客户端实现一些虚拟API,并使用它在计时器任务中对客户端执行ping操作。 You can optimize this ping interval based on the severity of the client registration's staleness. 您可以根据客户端注册的陈旧程度来优化此ping间隔。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM