1.先简单了解RPC与RMI的区别
RMI即远程方法调用,应用场景:本地有一个JAVA程序,需要调用一个方法,然而该方法可能很复杂,只有远程的机器上才有,这时候就需要通过RMI机制来调用。调用的过程也很简便,远程机器提供接口,本地只需要根据接口的形式提供对应的参数就可以。通讯的过程对客户端是透明的。
2.Demo1:实现本地调用远程方法进行相加add,采用值传递
(1)客户端需要的程序:
IHello.java (远程机器提供的接口)
HelloClient.java(客户端程序)
(2)服务器端需要的程序:
IHello.java (远程机器的接口)
HelloServer.java
HelloImpl(接口的实现)
(3)开发步骤
服务器端:
l 将接口在IHello.java文件中声明
- public interface IHello extends Remote {
- public int add(int x, int y) throws RemoteException;
- }
接口续继承Remote,并且要抛出RemoteException异常
l 接口的实现,在HelloImpl.java中完成
- public class HelloImpl extends UnicastRemoteObject implements IHello {public int add(int x, int y) throws RemoteException {
- return (x+y);
- }
- }
l 主函数写在HelloServer.java
- IHello rhello = new HelloImpl();
- LocateRegistry.createRegistry(7744);
- Naming.bind("rmi://localhost:7744/RHello", rhello);
将声明一个远程(remote`)对象,并将远程对象在服务器上注册,并将与一个uri绑定
客户端:
l 将服务器上的IHello.java接口文件拷贝到客户端
l 客户端的主程序卸载HelloClient.java中
- IHello rhello = (IHello) Naming
- .lookup("rmi://localhost:7744/RHello");
- Scanner sc=new Scanner(System.in);
- System.out.println("请输入要相加的值:");
- int x1=sc.nextInt();
- int y1=sc.nextInt();
- System.out.println(rhello.add(x1,y1));
客户端通过uri地址找到服务器创建的远程对象rhello,并调用远程方法。
运行结果:
注意:Client与Server的接口文件、包名需要一致
3.Demo2:采用远程方法进行数值交换,采用引用传递
JAVA中没有指针的概念,方法中传递的参数通常是值传递;然而值传递只是复制变量的数值,在远程服务器上执行后,本地的内存上没有任何变化,因此达不到数值交换的目的。
而JAVA中引用传递可以采用对象,数组等。对象在网络上传递必须进行串行化,写入Bytes流中,并能够从Bytes流中读出。
服务器端:
l 进行引用传递创建的对象 S.java
- public class S implements Serializable{
- private static final long serialVersionUID = 4765136455717773169L;
- private int x,y;
- ....
- }
l 在接口中IHello.java文件中增加方法的声明
- public S swap2(S s) throws RemoteException;
l 在HelloImpl.java中实现swap2方法
- public S swap2 (S s) throws RemoteException {...}
客户端:
l 拷贝 S.java到客户端
l 拷贝 IHell.java到客户端
l 客户端主程序
S s=new S(0,1);
// 在RMI服务注册表中查找名称为RHello的对象,并调用其上的方法
- try {
- IHello rhello = (IHello) Naming
- .lookup("rmi://localhost:7744/RHello");
- System.out.println("调用远程swap方法前:");
- System.out.println(s.getX());
- System.out.println(s.getY());
- System.out.println("调用远程swap方法后:");
- s=rhello.swap2(s);
- System.out.println(s.getX());
- System.out.println(s.getY());
- }
注意:Client与Server的对象的序列号需要一致
实验结果:
RMI (Remote Method Invocation)
RMI 采用stubs 和 skeletons 来进行远程对象(remote object)的通讯。stub 充当远程对象的客户端代理,有着和远程对象相同的远程接口,远程对象的调用实际是通过调用该对象的客户端代理对象stub来完成的,通过该机制RMI就好比它是本地工作,采用tcp/ip协议,客户端直接调用服务端上的一些方法。优点是强类型,编译期可检查错误,缺点是只能基于JAVA语言,客户机与服务器紧耦合。
RPC(Remote Procedure Call Protocol)
RPC使用C/S方式,采用http协议,发送请求到服务器,等待服务器返回结果。这个请求包括一个参数集和一个文本集,通常形成“classname.methodname”形式。优点是跨语言跨平台,C端、S端有更大的独立性,缺点是不支持对象,无法在编译器检查错误,只能在运行期检查。
(2)RMI 调用远程对象方法,允许方法返回 Java 对象以及基本数据类型,而RPC 不支持对象的概念