且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

我是否需要客户端,服务器和注册表上的所有类才能使用RMI?

更新时间:2023-10-17 21:15:22

在JDK之前v5必须使用 rmic RMI编译器)生成RMI存根。这是从JDK v5自动完成的。此外,您还可以从Java代码中启动RMI注册表。要从简单的RMI应用程序开始,您可能需要按照以下步骤操作:

Prior to JDK v5 one had to generate the RMI stubc using the rmic (RMI Compiler). This is done automatically from JDK v5 on. Moreover, you can start the RMI Registry from within the Java code as well. To start with a simple RMI application you may want to follow the following steps:



  1. 创建界面:

  1. Create the interface:

import java.rmi.*;
public interface SomeInterface extends Remote {
  public String someMethod1() throws RemoteException;
  public int someMethod2(float someParameter) throws RemoteException;
  public SomeStruct someStructTest(SomeStruct someStruct) throws RemoteException;
}





  • 实施界面:

  • Implement the interface:
    
    import java.rmi.*;
    import java.rmi.server.*;
    public class SomeImpl extends UnicastRemoteObject implements SomeInterface {
      public SomeImpl() throws RemoteException {
        super();
      }
      public String someMethod1() throws RemoteException {
        return "Hello World!";
      }
      public int someMethod2( float f ) throws RemoteException {
        return (int)f + 1;
      }
      public SomeStruct someStructTest(SomeStruct someStruct) throws RemoteException {
        int i = someStruct.getInt();
        float f = someStruct.getFloat();
        someStruct.setInt(i + 1);
        someStruct.setFloat(f + 1.0F);
        return someStruct;
      }
    }
    





  • 实现在客户端和服务器之间传递的非原始可序列化对象:

  • Implement a non-primitive serializable object that is to be passed between a client and the server:
    
    import java.io.*;
    public class SomeStruct implements Serializable {
      private int i = 0;
      private float f = 0.0F;
      public SomeStruct(int i, float f) {
        this.i = i;
        this.f = f;
      }
      public int getInt() {
        return i;
      }
      public float getFloat() {
        return f;
      }
      public void setInt(int i) {
        this.i = i;
      }
      public void setFloat(float f) {
        this.f = f;
      }
    }
    





  • 实现服务器:

  • Implement the server:
    
    import java.rmi.*;
    import java.rmi.server.*;
    import java.rmi.registry.Registry;
    import java.rmi.registry.LocateRegistry;
    import java.net.*;
    import java.io.*;
    public class SomeServer  {
      public static void main(String args[]) {
        String portNum = "1234", registryURL;
        try{   
          SomeImpl exportedObj = new SomeImpl();
          startRegistry( Integer.parseInt(portNum) );
          // register the object under the name "some"
          registryURL = "rmi://localhost:" + portNum + "/some";
          Naming.rebind(registryURL, exportedObj);
          System.out.println("Some Server ready.");
        } catch (Exception re) {
          System.out.println("Exception in SomeServer.main: " + re);
        }
      }
      // This method starts a RMI registry on the local host, if it
      // does not already exist at the specified port number.
      private static void startRegistry(int rmiPortNum) throws RemoteException{
        try {
          Registry registry = LocateRegistry.getRegistry(rmiPortNum);
          registry.list( );  
          // The above call will throw an exception
          // if the registry does not already exist
        } catch (RemoteException ex) {
          // No valid registry at that port.
          System.out.println("RMI registry is not located at port " + rmiPortNum);
          Registry registry = LocateRegistry.createRegistry(rmiPortNum);
          System.out.println("RMI registry created at port " + rmiPortNum);
        }
      }
    }
    





  • 实现客户端:

  • Implement the client:
    
    import java.io.*;
    import java.rmi.*;
    import java.rmi.registry.Registry;
    import java.rmi.registry.LocateRegistry;
    public class SomeClient {
      public static void main(String args[]) {
        try {
          String hostName;
          String portNum = "1234";
          String registryURL = "rmi://localhost:" + portNum + "/some";
          SomeInterface h = (SomeInterface)Naming.lookup(registryURL);
          // invoke the remote method(s)
          String message = h.someMethod1();
          System.out.println(message);
          int i = h.someMethod2(12344);
          System.out.println(i);
          SomeStruct someStructOut = new SomeStruct(10, 100.0F);
          SomeStruct someStructIn  = new SomeStruct(0, 0.0F);
          someStructIn = h.someStructTest(someStructOut);
          System.out.println( someStructIn.getInt() );
          System.out.println( someStructIn.getFloat() );
        } catch (Exception ex) {
          ex.printStackTrace();
        }
      }
    }
    



  • 较大的客户端 - 服务器应用程序应分为三个模块: client server common (对于服务器和客户端代码之间共享的类,即本例中的远程接口和非基本对象)。然后,客户端应用程序将从类路径上的客户端 + 公共模块和 server + common 模块。

    A larger client-server application should be divided into three modules:client, server, and common (for classes shared between the server and client code, i.e. the remote interface and the non-primitive object in this example). The client application will then be created from client + common modules on the classpath and the server from server + common modules on the classpath.

    我用这个例子很多年了以前学习RMI的基础知识,它仍然有效。然而,它远非完美(使用默认的Java包,不正确的异常处理,主机名和端口参数是硬编码的,不可配置等)。

    I used this example many years ago to learn basics of RMI and it still works. However it is far from being perfect (default Java package used, incorrect exception handling, hostname and port parameters are hard-coded and not configurable, etc.)

    然而,它对初学者有好处。所有文件都可以放在一个目录中,并使用简单的 javac * .java 命令进行编译。然后可以使用 java SomeServer 启动服务器应用程序,通过启动 java SomeClient 命令启动客户端。

    Nevertheless, it is good for starters. All the files can be placed in one directory and compiled using the simple javac *.java command. The server application can then be started using the java SomeServer and the client one by launching the java SomeClient command.

    我希望这有助于理解Java RMI,事实上,它远比这复杂得多。

    I hope this helps to understand the Java RMI which is, in fact, far more complicated than just this.