首页 文章

如何在java中创建rmi [关闭]

提问于
浏览
-1

嗨,我已经搜索了互联网很长一段时间试图找到一些事情谈论如何在Windows 7中使用cmd启动rmi注册表,所以如果有人知道如何做这个请求让我知道如何做到或如果任何一个可以提前为我们提供一个良好的链接... thx

好吧谢谢所有人如何回答我的问题,当我问我不完全理解RMI系统或它是如何工作的问题但知道我有个好主意我会总结这个为RMI系统提供所有想法,如果我有任何错误请纠正我

所以

远程接口:

  • 我们需要一个从Remote类扩展的接口,并定义了我们想要远程调用的方法
    注意:Remote是一个"marker"接口,用于标识可以从非本地虚拟机调用其方法的接口 .
import java.rmi.Remote; 
import java.rmi.RemoteException; 
import java.util.Calendar; 

public interface CalendarTask extends Remote { 

  Calendar getDate() throws RemoteException; 

}

远程对象:

  • 我们需要创建一个Remote对象的类,所以我们创建一个类对象实现Remote Interface来创建由这个类对象创建的对象远程对象,并通过从这个类UnicastRemoteObjec的扩展将这个对象链接到RMI系统,所以当一个类扩展时从UnicastRemoteObject,它必须提供一个构造函数,声明这个构造函数调用super(),它激活UnicastRemoteObject中的代码,该代码执行RMI链接和远程对象初始化 .
import java.rmi.RemoteException; 
import java.rmi.server.UnicastRemoteObject; 
import java.util.Calendar; 

 public class CalendarImpl extends UnicastRemoteObject implements CalendarTask { 

  private int counter = 1; 

   public CalendarImpl() throws RemoteException {} 

   public Calendar getDate() throws RemoteException{

  System.out.print("Method called on server:"); 
  System.out.println("counter = " + counter++); 
  return Calendar.getInstance(); 
  } 
}

编写服务器:

3.1服务器的工作是接受来自客户端的请求,执行某些服务,然后将结果发送回客户端 .

3.2服务器必须指定一个接口,该接口定义客户端作为服务可用的方法 . 我们在第一步(远程接口)上面做了

3.3服务器创建远程对象,以任意名称注册它,然后等待远程请求

3.4因此对于register我们使用java.rmi.registry.LocateRegistry类的远程对象允许通过调用其createRegistry()方法在代码中启动RMI注册表服务(作为JVM的一部分提供) .

3.5 java.rmi.registry.Registry类提供了两种将对象绑定到注册表的方法 .

•Naming.bind(“ArbitraryName”,remoteObj);如果对象已绑定在“ArbitrayName”下,则抛出异常 .

•Naming.rebind(“ArbitraryName”,remoteObj);如果它不存在,则绑定“ArbitraryName”下的对象或覆盖绑定的对象 .

3.6以下示例充当创建CalendarImpl对象的服务器,并通过以“TheCalendar”名称绑定它来使其可供客户端使用

import java.rmi.Naming; 
  import java.rmi.registry.LocateRegistry; 

  public class CalendarServer { 

  public static void main(String args[]) { 
      System.out.println("Starting server..."); 
      // Start RMI registry service and bind 
      // object to the registry 
      try { 
          LocateRegistry.createRegistry(1099); 
          Naming.rebind("TheCalendar", 
                  new CalendarImpl()); 
      } catch (Exception e) { 
          e.printStackTrace(); 
          System.exit(1); 
      } 
      System.out.println("Server ready"); 
   } 
 }

写客户:

4.1 RMI客户端是访问远程对象提供的服务的程序

4.2 java.rmi.registry.LocateRegistry类允许客户端通过其getRegistry()方法定位RMI注册表服务

4.3 java.rmi.registry.Registry类提供了一个lookup()方法,该方法接受服务器绑定的远程对象的“ArbitraryName” .

一旦客户端获得对远程对象的引用,它就会调用方法,就好像该对象是本地对象一样

import java.rmi.registry.*; 
import java.util.Calendar; 

public class CalendarClient { 

  public static void main(String args[]) { 
      Calendar c = null; 
      CalendarTask remoteObj; 
      String host = "localhost"; 
      if(args.length == 1) 
          host = args[0]; 
      try { 
          Registry r = 
            LocateRegistry.getRegistry(host, 1099);
            Object o = r.lookup("TheCalendar"); 
            remoteObj = (CalendarTask) o; 
            c = remoteObj.getDate(); 
      } catch (Exception e) { 
          e.printStackTrace(); 
      } 
      System.out.printf("%tc", c); 
    } 
  }

1 回答

  • 1

    您编写的代码不会启动注册表 . LocateRegistry.getRegistry() 不这样做 . 检查Javadoc . 它假定注册表已在运行 . LocateRegistry.getRegistry() 只根据您提供的主机和端口构建一个注册表存根 . 它甚至没有进行任何网络操作 .

    要从JVM中启动注册表,请使用 LocateRegistry.createRegistry(), 作为其Javadoc状态 .

    编辑:您的编辑中有很多错误信息 .

    Remote是一个“标记”接口,用于标识可以从非本地虚拟机调用其方法的接口 .

    仅当导出的远程对象已将其存根传输到该VM时才实现 . 远程接口本身没有任何这样的神奇属性 . 必须声明远程接口中定义的所有方法都抛出 RemoteException, ,尽管这些方法的实现通常不需要如此声明(即除非它们自己执行远程操作:编译器会告诉你) .

    我们需要创建Remote对象的类,所以我们创建类对象实现远程接口来创建由此类对象创建的对象

    这里太混乱了 . 我们需要一堂课 . 该类必须实现远程接口 . 这不是'object':它是一段必须编译为.class文件的代码 . 一个类没有't '使对象' . 应用程序使用 new 运算符执行此操作 .

    我们通过此类UnicastRemoteObjec扩展将此对象链接到RMI系统,因此当一个类从UnicastRemoteObject扩展时,它必须提供一个构造函数,声明此构造函数调用super(),它激活UnicastRemoteObject中的代码,该代码执行RMI链接和远程对象初始化

    RMI中没有'link'步骤 . 有一个'export'步骤 . 它通过扩展 UnicastRemoteObject 或通过调用 UnicastRemoteObject.exportObject(). 执行如果你不扩展 UnicastRemoteObject 你不需要构造函数你描述 .

    服务器的工作是接受来自客户端的请求,执行某些服务,然后将结果发送回客户端 .

    服务器的工作是在远程接口中实现方法 . RMI为您完成所有其他工作 .

    服务器创建远程对象,以任意名称注册它,然后等待远程请求

    否则服务器是远程对象并且它自己注册 .

    for register我们使用java.rmi.registry.LocateRegistry类的远程对象允许通过调用其createRegistry()方法在代码中启动RMI注册表服务(作为JVM的一部分提供) .

    或者您可以通过 rmiregistry 命令使用外部注册表 . 或者您可以通过JNDI使用LDAP服务器 .

    LocateRegistry.createRegistry(1099); 
    Naming.rebind("TheCalendar", 
                  new CalendarImpl());
    

    除非将 createRegistry() 的结果存储到静态变量中,否则这将不起作用 . 存储它之后,您也可以使用它来执行绑定,而不是使用 Naming 类 . 如果不将它存储到静态变量中,它将被垃圾收集,远程对象也将被垃圾收集 .

    java.rmi.registry.LocateRegistry类允许客户端通过其getRegistry()方法定位RMI注册表服务

    或者你可以使用 Naming 类,见下文 .

    java.rmi.registry.Registry类提供了一个lookup()方法,该方法接受服务器绑定的远程对象的“ArbitraryName” .

    Naming 类也是如此 . 它需要一个rmi:URL来指定主机和端口以及bind-name . 您可以省略 rmi:// 部分 . 如果省略主机,则默认为'localhost',但这仅在客户端与服务器在同一主机中运行时才有用,这本身并不是非常有用 . 如果省略端口,则默认为1099 .

相关问题