RMI小例子一枚

 一个正常工作的RMI系统由下面几个部分组成:

  ·远程服务的接口定义

  ·远程服务接口的具体实现

  ·桩(Stub)和框架(Skeleton)文件 (JDK1.5以后自动生成

  ·一个运行远程服务的服务器

  ·一个RMI命名服务,它允许客户端去发现这个远程服务

  ·类文件的提供者(一个HTTP或者FTP服务器

  ·一个需要这个远程服务的客户端程序


远程服务的接口定义   Server.java:

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Server extends Remote{ //必须继承Remote接口

String hellpWorld(String name) throws RemoteException;

Person getPerson(String name,int age)throws RemoteException;

}

Person对象(网络传输,必须实现序列化):

import java.io.Serializable;

public class Person implements Serializable{
private String name;
private int age;

public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}

}

远程服务接口的具体实现  ServerImpl.java:

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;

//必须继承UnicastRemoteObject对象
public class ServerImpl extends UnicastRemoteObject implements Server {

protected ServerImpl() throws RemoteException {
super();
}

public String hellpWorld(String name) throws RemoteException {
return name+"你好";
}

public Person getPerson(String name, int age) throws RemoteException {
return new Person(name,age);
}
//没有在接口里定义的方法是本地方法不能被远程调用
public void info(){
System.out.println("我是本地方法");
}

public static void main(String[] args) throws RemoteException, MalformedURLException {
Server imp=new ServerImpl();
//注册远程服务的端口
LocateRegistry.createRegistry(1097);
Naming.rebind("rmi://:1097/jim", imp);
}

}

客户端:

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

public class RMIClient {

/**
*
@param args
*
@throws NotBoundException
*
@throws RemoteException
*
@throws MalformedURLException
*/
public static void main(String[] args) throws MalformedURLException, RemoteException, NotBoundException {
Server ser=(Server) Naming.lookup("rmi://:1097/jim");
System.out.println(ser.hellpWorld("jim"));
System.out.println(ser.getPerson("jim", 24));
}

}

 

当客户端面向远程服务接口调用远程方法之后,接下来要经过如下几个步骤:

  1. 本地客户端调用远程服务对象的方法------实际上是调用Stub对象的方法。
  2. Stub对象其实就是远程服务对象在客户端的代理。Stub对象会对调用请求进行编码,保证远程调用请求可以在网络上传输。所以这一步要求调用远程方法的所以参数都是可序列化的。
  3. 通过底层网络传输将请求传递到Skeleton。
  4. Skeleton收到Stub通过网络传输过来的调用请求后,Skeleton对请求进行解码,将请求转换为满足远程服务对象要求的请求
  5. Skeleton将解码后的请求发送到远程服务对象,让远程服务对象来负责处理调用请求。
  6. Skeleton收到远程服务对象的执行结果(就是方法返回值)后,再次对执行结果进行编码,因此这一步要求RMI中的方法返回值都是可序列化。
  7. 通过底层网络传输将处理结果送到Stub
  8. Stub解码处理结果
  9. Stub将解码后的符合本地客户端要求的结果送给本地客户端
  10. 本地客户端收到执行结果。假象就是:本地客户端成功地调用了远程java方法。

 

 

 


posted @ 2012-03-25 13:05  一直在等  阅读(1274)  评论(0编辑  收藏  举报