在java的开发中不可避免的遇到java网络编程,RMI,EJB的使用,他们的关系是什么呢? RMI,远程方法调用(Remote Method Invocation)是Enterprise JavaBeans的支柱,是建立分布式Java应用程序的方便途径。RMI是非常容易使用的,但是它非常的强大。RMI的基于特定接口,RMI构架基于一个重要的原理:定义接口和定义接口的具体实现是分开的。
RMI基本原理
要实现网络机器间的通讯,首先得来看看计算机系统网络通信的基本原理,在底层层面去看,网络通信需要做的就是将流从一台计算机传输到另外一台计算机,基于传输协议和网络IO来实现,其中传输协议比较出名的有http、tcp、udp等等,http、tcp、udp都是在基于Socket概念上为某类应用场景而扩展出的传输协议,网络IO,主要有bio、nio、aio三种方式,所有的分布式应用通讯都基于这个原理而实现,只是为了应用的易用,各种语言通常都会提供一些更为贴近应用易用的应用层协议。
由此可知RMI底层采用网络编程的,既RMi基于套接字编程的,RMI是EJB远程调用的基础,仅用RMI技术就可以实现远程调用,使用EJB是为了实现组件,事物,资源池,集群等功能。
下面RMI学习:
服务接口:
package com.easyway.space.basic.network.sockets.rmi;
import java.rmi.Remote;
import java.rmi.RemoteException;
/**
* Rmi服务接口
* 创建远程接口及声明远程方法
* 远程服务接口实现java.rmi.Remote 的接口
*
* @author longgangbai
*
*/
public interface RmiMonitorService extends Remote{
public int interactive(int funindex ,String param)throws RemoteException;
}
服务接口的实现:
package com.easyway.space.basic.network.sockets.rmi;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
/**
* Rmi服务接口的实现
* 实现远程接口及远程方法(继承UnicastRemoteObject)
* RMI 实现UnicastRemoteObject类必须实现相关的空构造函数并抛出RemoteException
* @author longgangbai
*
*/
public class RmiMonitorServiceImpl extends UnicastRemoteObject implements RmiMonitorService{
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* 空构造函数
* @throws RemoteException
*/
protected RmiMonitorServiceImpl() throws RemoteException {
super();
}
/**
* 服务请求频率和监控信息
* @param funindex
* @param param
*/
public int interactive(int funindex, String param) throws RemoteException {
return funindex;
}
}
启动并注册RMI服务:
package com.easyway.space.basic.network.sockets.rmi;
import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
/**
* Rmi远程监控的服务端
*
* 启动RMI注册服务,并注册远程对象
*
* @author longgangbai
*
*/
public class RmiMonitorServer {
public String host="localhost";
public int port=8889;
/**
* 初始化远程服务的方法
*/
public void init(){
try {
//注册本地端口
LocateRegistry.createRegistry(port);
RmiMonitorService monitor=new RmiMonitorServiceImpl();
//rmi绑定本地目录和命名服务
Naming.bind("//"+host+":"+port+"/monitor",monitor);
} catch (MalformedURLException e) {
System.out.println("发生URL异常!" +e.getMessage());;
} catch (AlreadyBoundException e) {
System.out.println("发生重复绑定对象异常!" +e.getMessage());
}catch (RemoteException e) {
System.out.println("创建远程对象发生异常!" +e.getMessage());
}
}
public static void main(String[] args) {
RmiMonitorServer rmi=new RmiMonitorServer();
System.out.println("RMI服务初始化.....");
rmi.init();
}
}
客户端查找并使用存根:
package com.easyway.space.basic.network.sockets.rmi;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.HashMap;
import java.util.Map;
/**
* Rmi监控的客户端的服务
*
* 客户端查找远程对象,并调用远程方法
*
* @author longgangbai
*
*/
public class RmiMonitorClient {
//用户缓存使用的实例
public Map<Class,Object> serviceMap=new HashMap<Class,Object>();
public RmiMonitorService monitorService;
public String ip="localhost";
public int port=8889;
public int interactive(int funindex ,String param)
{
try {
if(monitorService==null)
{
monitorService=getMonitorService(RmiMonitorService.class);
}
return monitorService.interactive(funindex, param);
} catch (RemoteException e) {
e.printStackTrace();
}
return 0;
}
/**
* 查找服务对象的应用
* @param clazz
* @return
*/
public RmiMonitorService getMonitorService(Class clazz){
try {
Object object=serviceMap.get(clazz);
if(object==null)
{
monitorService=(RmiMonitorService)Naming.lookup("rmi://"+ip+":"+port+"/monitor");
serviceMap.put(RmiMonitorService.class, monitorService);
}else{
monitorService=(RmiMonitorService)serviceMap.get(clazz);
}
return monitorService;
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NotBoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return monitorService;
}
public static void main(String[] args) {
RmiMonitorClient client=new RmiMonitorClient();
int result=client.interactive(9, "i love you");
System.out.println("result ="+result);
}
}