5、任务接口实现
该实现定义了远程方法需要传递的参数
package com.liuxiang.rmi.download;
/**
* 任务实现类
* @author liuxiang
* 2007-8-31 上午09:08:57
*
*/
public class TaskImpl implements ITask{
public Object doWork() {
System.out.println("当前程序处于远程调用中");
return "动态上载对象的返回值";
}
}
6、编写服务器程序 、注册远程对象、启动远程对象
代码:远程对象的注册类 该类应该在服务器端执行 执行之后, 该机器将变为RMI服务器 客户端可以通过正确的url来访问;服务器上的远程对象;执行对外报露的方法
/**
*
*/
package com.liuxiang.rmi.download;
import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
/**
* 远程对象的注册类 该类应该在服务器端执行 执行之后,
* 该机器将变为RMI服务器 客户端可以通过正确的url来访问
* 服务器上的远程对象;执行对外报露的方法
*
* @author liuxiang 2007-8-30 下午09:44:54
*
*/
public class RMIServer {
/**
* 如果没有创建一个Registry,Naming是不会帮助你创建的。 还是自己手工创建的比较的好
*
* 尽量用下面的自己封装的bind方法来注册远程对象
*
* @throws Exception
*/
public static void registRemoteObject() throws Exception {
IRMIImpl impl = new IRMIImpl();
Naming.rebind("rmi://219.233.8.97:1111/mytask", impl);
System.out.println("bound success!");
}
/**
* 创建一个Registry对象
*
* @return 返回一个Registry对象
*/
private static Registry createRegistry() {
Registry registry = null;
int port = 1111;
try {
registry = LocateRegistry.getRegistry(port);
registry.list();
System.out.println("Register the exist server!");
} catch (final Exception e) {
try {
registry = LocateRegistry.createRegistry(port);
System.out.println("Register the exist server!port=" + port);
} catch (final Exception ee) {
ee.printStackTrace();
}
}
return registry;
}
/**
* 将对象注册到rmi服务器上
*/
public static void bind() {
Registry registry = null;
registry = createRegistry();
try {
IRMIImpl impl = new IRMIImpl();
registry.rebind("mytask", impl);
System.out.println("mytask server start!");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @param args
*/
public static void main(String[] args) {
try {
bind();
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行该服务端代码后,将会注册一个远程服务对象,通过恰当的URL可以访问远程对象中的方法;运行后的结果如下:
Register the exist server!port=1111
mytask server start!
7、编写客户程序
代码首先获取一个远程对象,然后如同本地调用一样,调用远程对象中的方法。
/**
*
*/
package com.liuxiang.rmi.download;
import java.rmi.Naming;
/**
* @author liuxiang
* 2007-8-30 下午09:47:41
*
*/
public class RMIClient {
/**
* 调用远程对象中的方法
* @throws Exception
*/
public static void getRemoteObject() throws Exception{
IRMI obj = (IRMI)Naming.lookup("rmi://localhost:1111/mytask"); //得到远程发布的服务
TaskImpl task = new TaskImpl();
Object result = obj.invoke(task); //调用远程服务的方法
System.out.println(result.toString());
}
/**
* @param args
*/
public static void main(String[] args) {
try {
getRemoteObject();
} catch (Exception e) {
e.printStackTrace();
}
}
}
最后,运行客户端代码,可以看到控制台分别输出了如下的内容:
Server端输出了更多的内容,如下:
Register the exist server!port=1111
mytask server start!
注意:这是一个远程调用
当前程序处于远程调用中
调用ITask.doWork()方法的返回值:动态上载对象的返回值
同时可以看到,会调用了Windows的Mediaplay播放本地磁盘的Mp3歌曲;
Client端输入了如下内容:
动态上载对象的返回值
四、RMI介绍
RMI(Remote Method Invocation,远程方法调用)是用Java在JDK1.1中实现的,它大大增强了Java开发分布式应用的能力。Java作为一种风靡一时的网络开发语言,其巨大的威力就体现在它强大的开发分布式网络应用的能力上,而RMI就是开发百分之百纯Java的网络分布式应用系统的核心解决方案之一。其实它可以被看作是RPC的Java版本。但是传统RPC并不能很好地应用于分布式对象系统。而Java RMI 则支持存储于不同地址空间的程序级对象之间彼此进行通信,实现远程对象之间的无缝远程调用。
RMI目前使用Java远程消息交换协议JRMP(Java Remote Messaging Protocol)进行通信。JRMP是专为Java的远程对象制定的协议。因此,Java RMI具有Java的"Write Once,Run Anywhere"的优点,是分布式应用系统的百分之百纯Java解决方案。用Java RMI开发的应用系统可以部署在任何支持JRE(Java Run Environment Java,运行环境)的平台上。但由于JRMP是专为Java对象制定的,因此,RMI对于用非Java语言开发的应用系统的支持不足。不能与用非Java语言书写的对象进行通信。
RMI为采用Java对象的分布式计算提供了简单而直接的途径。这些对象可以是新的Java对象,也可以是围绕现有API的简单的Java包装程序。Java体现了“编写一次就能在任何地方运行的模式。而RMI可将Java模式进行扩展,使之可在任何地方运行”。
因为RMI是以Java为核心的,所以,它将Java的安全性和可移植性等强大功能带给了分布式计算。您可将代理和梢?务逻辑等属性移动到网络中最合适的地方。如果您要扩展Java在系统中的使用,RMI将使您充分利用其强大功能。
RMI可利用标准Java本机方法接口JNI与现有的和原有的系统相连接。RMI还可利用标准JDBC包与现有的关系数据库连接。RMI/JNI和RMI/JDBC相结合,可帮助您利用RMI与目前使用非Java语言的现有服务器进行通信,而且在您需要时可扩展Java在这些服务器上的使用。RMI可帮助您在扩展使用时充分利用Java的强大功能。