Java 通过RMI而不使用注册表的服务器
我有一个可以通过RMI连接到的服务对象。目前我正在这样做: 服务器Java 通过RMI而不使用注册表的服务器,java,networking,registry,rmi,rmiregistry,Java,Networking,Registry,Rmi,Rmiregistry,我有一个可以通过RMI连接到的服务对象。目前我正在这样做: 服务器 Registry r = LocateRegistry.createRegistry(1234); r.bind("server", UnicastRemoteObject.exportObject(remoteServer, 0)); 客户端 RemoteServer s = LocateRegistry.getRegistry("example.com", 1234).lookup("server"); 服务器上的注册表
Registry r = LocateRegistry.createRegistry(1234);
r.bind("server", UnicastRemoteObject.exportObject(remoteServer, 0));
客户端
RemoteServer s = LocateRegistry.getRegistry("example.com", 1234).lookup("server");
服务器上的注册表只有一个用途,即链接到单个服务器对象。我想我也可以在服务器上这样做:
UnicastRemoteObject.exportObject(remoteServer, 1234);
但是,我如何从客户端连接到服务器对象呢?这不是不可能的,但不是非常实用,因为注册表将导出对象的存根对象传递给客户端(请参阅)。如果你没有另一种机制,你会被卡住的。在分布式系统中使用注册表还有其他好处,因此我建议出于其他原因(位置透明性等)保留它。RMI注册表的存在是为了解决RMI引导问题,即您只能通过远程方法调用获取远程存根,要执行远程方法调用,需要一个远程存根。
LocateRegistry.getRegistry()
提供的注册表引用解决了此问题(如果您正在使用该API,则由Naming.lookup()
在内部使用)。[请注意,此存根不是通过远程方法获得的:它是使用您提供的主机:端口在本地合成的。如果它们不正确,则在使用注册表存根之前,您将无法找到。]
您有几种选择来解决RMI引导问题:
UnicastRemoteObject,
序列化导出对象时获得的存根,并使用共享文件、套接字或sneakernet使存根可供客户端使用您可以看到,注册表无疑是最简单的选择。请注意,您只需使用它来解决引导问题。一旦有了存根,您自己的应用程序远程方法就可以返回更多的对象:您不需要在注册表中有多个远程对象。您可以将其视为远程对象工厂。
客户端使用RMI URLrmi://localhost:2020/server
请参见Vista:这是不正确的,您提供的链接也没有说明这一点。注册表所做的只是解决引导问题:您只能作为远程方法的结果获取远程存根,为此您需要远程存根…Vista:否。引导问题是向客户端提供初始存根对象,正如您的链接所述。你说的是“课堂”,这是完全错误的。注册表不提供类。您关于“对象的新实例”的“新存根类”的第二句话也没有任何意义。@EJB:如果问题是类与对象的使用之间的问题,我同意您的意见,并且已经纠正了这一点。我的主要观点是存根的来源和登记册的必要性,这显然是问题的精神所在。顺便说一句,我无法编辑上面的评论,所以我正在删除它。我再次遇到这个问题(),这次无法使用注册表。我可以使用方法3,但如果客户端拥有接口和服务的主机/端口,它是否可以自己合成存根?@BartvanHeukelom理论上是的,实际上不是。为什么不能使用注册表呢?很好的提示(3)它只是需要以某种方式传输到客户端的序列化存根。从来没有从文档中了解到这有那么容易。现在zookeeper也是一个不错的选择。对于(3)来说,值得注意的是,设置系统属性
java.rmi.server.hostname
似乎是获取存根的唯一方法,存根可以从一台机器连接到另一台机器,而不仅仅是本地主机。@Harald仅当导出主机的DNS配置错误时,或者存在公共/私有IP地址问题。