【发布时间】:2014-03-13 03:47:57
【问题描述】:
我正在通过 Java RMI 编写一个分布式应用程序。 RMI客户端向RMI服务器注册事件处理程序/回调,服务器在需要时调用客户端的回调函数。现在的问题是,当网络连接失败时(例如,网线拔掉了……),RMI服务器和客户端不会得到通知,并且当尝试调用客户端注册的回调函数时,RMI服务器会失败。RMI服务器也无法将此问题通知 RMI 客户端。更糟糕的是,当网络连接恢复时,RMI 客户端服务仍然会失去与 RMI 服务器的联系,因为没有人通知她重新连接。
我目前的想法是在单独的线程中在 RMI 客户端中实现一个 ping() 方法。 该线程可以定期唤醒并检查服务器。 如果失败,则闹剧重新连接。
还有其他优雅的解决方案吗?希望大家帮忙!
界面
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface MyInterface extends Remote {
public int RegisterEventHandler(RemoteMyEventHandler eventHandler) throws RemoteException;
public void unRegisterEventHandler(int eventHandlerId) throws RemoteException;
}
RMI 服务器实现
import java.rmi.RemoteException;
import com.me.MyInterface;
public class MyInterfaceImpl implements MyInterface {
{
public void init() {
try {
//... initialize RMI server....
//....
} catch (Exception ex) {
ex.printStackTrace();
}
}
@Override
public int RegisterEventHandler(RemoteMyEventHandler eventHandler)
throws RemoteException {
return MyEventHandlerImp.getInstance().addHandler(eventHandler);
}
@Override
public void unRegisterEventHandler(int eventHandlerId)
throws RemoteException {
MyEventHandlerImp.getInstance().removeHandler(eventHandlerId);
}
}
//handler.notifyEventSnap(events);
RMI 客户端实现
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.Properties;
import org.apache.log4j.Logger;
import com.me.MyInterface;
public class MyService implements NotifyHandler{
{
private MyInterface client;
private MyEventHandler myEventHandler;
private void connectToServer() {
try {
//...
Registry registry = LocateRegistry.getRegistry(rmiHost, rmiPort);
client = (MyInterface) registry.lookup(MyCInterface.class.getName());
} catch (RemoteException er) {
} catch (NotBoundException en) {
} catch (Exception en) {
}
}
private void startService(){
//Attach my event handler
if(client != null)
{
myEventHandler = new MyEventHandler();
myEventHandlerId = client.RegisterEventHandler(myEventHandler);
}
}
}
【问题讨论】:
-
你需要看的是RMI Timeout post
-
网络中断后,客户端不必“联系服务器重新连接”。存根仍然有效,服务器只需要再试一次。
-
@EJP,你是什么意思?正如我测试的那样,客户端必须再次调用'registry.lookup...',否则会抛出RemoteException
-
除非服务器 JVM 重新启动或服务器取消导出其远程对象,否则不会。请提供他的堆栈跟踪。将其编辑到您的问题中。