1.RMI 目前使用Java远程消息交 换协议JRMP(Java Remote Messaging Protocol)进行通信。JRMP是专为Java的远程对象制定的协议。因此,Java RMI具有Java的“Write Once,Run Anywhere”的优点,是分布式应用系统的百分之百纯Java解决方案。用Java RMI开发的应用系统可以部署在任何支持JRE(JavaRun Environment Java,运行环境)的平台上。但由于JRMP是专为Java对象制定的,因此,RMI对于用非Java语言开发的应用系统的支持不足。不能与用非Java语言书写的对象进行通信。
2.一个正常工作的RMI系统由下面几个部分组成:
1)远程服务的接口定义,该接口必须实现Remote接口,Remote接口仅仅是一个没有方法的标记型接口;
2)远程服务接口的具体实现,写一个实现类继承UnicastRemoteObject类然后实现自己定义的那个远程接口;
3)桩(Stub)和框架(Skeleton)文件,stub是远程对象的客户端代理,通过它可以实现远程方法的调用,而skeleton是服务器端的骨架,将stub的调用具体分配给实际的远程对象实现;
4)一个运行远程服务的服务器
5)一个RMI命名服务,它允许客户端去发现这个远程服务
6)类文件的提供者(一个HTTP或者FTP服务器)
7)一个需要这个远程服务的客户端程序
3.具体实现的四个步骤:
1. 创建远程接口及声明远程方法(HelloInterface.java)
2. 实现远程接口及远程方法(继承UnicastRemoteObject)(Hello.java)
3. 启动RMI注册服务,并注册远程对象(HelloServer.java)
4. 客户端查找远程对象,并调用远程方法(HelloClient)
5. 执行程序:启动服务HelloServer;运行客户端HelloClient进行调用
4.代码实现:
1) 创建远程接口及声明远程方法(HelloInterface.java)
java 代码
packagecom.unmi;
import java.rmi.*;
/**
* 远程接口必须扩展接口java.rmi.Remote
*/
public interface HelloInterface extends Remote {
/**
* 远程接口方法必须抛出java.rmi.RemoteException
*/
public String say() throws RemoteException;
}
2) 实现远程接口及远程方法(继承UnicastRemoteObject)Hello.java
如果传递参数,参数必须是可序列化的参数实现java.io.Serializable
java 代码
packagecom.unmi;
importjava.rmi.*;
importjava.rmi.server.*;
/**
* 扩展了UnicastRemoteObject类,并实现远程接口 HelloInterface
*/
publicclass Hello extends UnicastRemoteObject implements HelloInterface {
private Stringmessage;
/**
* 必须定义构造方法,即使是默认构造方法,也必须把它明确地写出来,因为它必须抛出出RemoteException异常
*/
public Hello(Stringmsg) throws RemoteException
{
message = msg;
}
/**
* 远程接口方法的实现
*/
public String say() throws RemoteException
{
System.out.println("Called by HelloClient");
returnmessage;
}
}
3) 启动RMI注册服务,并注册远程对象(HelloServer.java)
java 代码
packagecom.unmi;
importjava.rmi.Naming;
importjava.rmi.registry.LocateRegistry;
publicclass HelloServer {
/**
* 启动 RMI 注册服务并进行对象注册
*/
public static void main(String[]argv)
{
try
{
//启动RMI注册服务,指定端口为1099 (1099为默认端口)
//也可以通过命令 $java_home/bin/rmiregistry1099启动
//这里用这种方式避免了再打开一个DOS窗口
//而且用命令rmiregistry启动注册服务还必须事先用RMIC生成一个stub类为它所用
LocateRegistry.createRegistry(1099);
//创建远程对象的一个或多个实例,下面是hello对象
//可以用不同名字注册不同的实例
HelloInterface hello = new Hello("Hello,world!");
//把hello注册到RMI注册服务器上,命名为Hello
Naming.rebind("Hello",hello);
//如果要把hello实例注册到另一台启动了RMI注册服务的机器上
//Naming.rebind("//192.168.1.105:1099/Hello",hello);
System.out.println("Hello Server is ready.");
}
catch(Exception e)
{
System.out.println("Hello Server failed: " + e);
}
}
}
4) 客户端查找远程对象,并调用远程方法(HelloClient)
java 代码
packagecom.unmi;
importjava.rmi.Naming;
publicclass HelloClient {
/**
* 查找远程对象并调用远程方法
*/
public static void main(String[]argv){
try{
HelloInterface hello = (HelloInterface)Naming.lookup("Hello");
//如果要从另一台启动了RMI注册服务的机器上查找hello实例
//HelloInterfacehello = (HelloInterface)Naming.lookup("//192.168.1.105:1099/Hello");
//调用远程方法
System.out.println(hello.say());
}
catch(Exception e)
{
System.out.println("HelloClient exception: " + e);
}
}
}
5)执行程序:启动服务HelloServer;运行客户端HelloClient进行调用
代码如何编译这里就不细讲
(1)打开一个Dos窗口执行命令 java com.unmi.HelloServer 启动服务HelloServer
E:workspaceTestRMIbin>java com.unmi.HelloServer
Hello Server is ready.
运行成功则可以看到Hello Server is ready
(2)打开另一个Dos窗口执行命令 java com.unmi.HelloClient 运行客户端程序
E:workspaceTestRMIbin>java com.unmi.HelloClient
Hello, world!
调用成功则可以看到 Hello,world!
并且在启动服务端的窗口中看到紧跟 Hello Server is ready. 打印出
Called by HelloClient
6)到这里就全部完成,测试使用!