希望这个小架构能够经过各位的修改及调整之后给各位不管是对于研究或是事业上能够帮上一点小小的忙,接着我们就准备进入RMI章节了Remote Method Invocation(RMI) RMI,是Java所提供的分布式架构的机制,可以用来撰写成是和成是之间的通讯方法,当然你也可以透过Socket来撰写分散的程序(如前一个段落我们所介绍的),但是在使用这些函数需要做相当多繁琐的调整,另外再使用Socket通讯的时候,只能够传递资料,但是是若使用RMI技术不仅可以传递资料也能够传递对象呢!!所以各位只要好好的发挥您的想象力,想想您的程序架构就可以了!
RMI原理介绍 我们先看一下下面的联机是意图吧!!在分散室的架构中我们将程序分为Client及Server两端,再使用RMI的机制的时候Client会透过Server的Stub(向是Server的分身)透过RMI的一些运算找到Server的Skeleton,接着Client端就透过控制Server的分身就能够达到使用Server的函示及资源了。
图 RMI联机示意图 RMI联机过程说明 如图所示,虽然使用起来RMI感觉是相当的容易的,但是其实他包含了下面几个重要的动作,Client先透过Server的Stub联机的一个注册中心,接着注册中心将Stub和Server的Skeleton联机,然后Client端就可以使用Server端的资源。
图 RMI联机示意图 // CustWork.java 定义Server端提供服务的接口
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface CustWork extends Remote{
public String getSvrMsg() throws RemoteException;
}
// CustWorkImpl.java 这是Server端的服务
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Calendar;
import java.rmi.server.*;
public class CustWorkImpl implements CustWork{
public CustWorkImpl() throws RemoteException{
UnicastRemoteObject.exportObject(this);
}
public String getSvrMsg() throws RemoteException{
String threadName = Thread.currentThread().getName();
String curTime = Calendar.getInstance().getTime().toString();
System.out.println(threadName+" : Aclient connected at "+ curTime);
return (threadName + " :Message from Server at "+curTime);
}
}
// JSESocketFactory在程序中激活RMI的注册中心及Server服务
import java.rmi.registry.*;
import java.rmi.*;
import java.rmi.RMISecurityManager;
public class JSESocketFactory
{
public static void main(String[] args){
try {
//小技巧
Registry regObj = LocateRegistry.createRegistry(1099);
CustWorkImpl obj = new CustWorkImpl();
Naming.rebind("myServer", obj);
System.out.println
("myImpl created and bound in the registry to the name myServer");
}
catch (Exception e)
{
System.out.println("myImpl.main: an exception occurred:");
e.printStackTrace();
}
}
}
//RMIClient.java Client端的程序
//程序中有关IP的部分请填入Server的IP Address
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.RMISecurityManager;
public class RMIClient
{
static String servMsg ="";
public static void main(String[] args)
{
try{
if(System.getSecurityManager() == null)
System.setSecurityManager(new RMISecurityManager());
CustWork serRef =
(CustWork) Naming.lookup("rmi://192.168.0.1:1099/myServer");
servMsg = serRef.getSvrMsg();
System.out.println(servMsg);
}catch(Exception e)
{
e.printStackTrace();
}
}
}
编译及执行程序 注意此部分的编译方法为jdk1.1.8的编译方法,若想在计算机中当Server且和J2SE联机的话,你需要设定C:\jdk1.3.1\jre\lib\ security 中的 java.policy 一些联机权限的设定,另外产生 stub 及 skeleton 的时候也需要使用rmic –v1.1的参数,因为 Perosnal Java 是参照jdk.1.1.x的规格实作出来的。
编译程序Server端的Interface及Service
c:\jdk1.1.8\bin\javac –classpath %pjeeclasspath%;. CustWork.java(1)
c:\jdk1.1.8\bin\javac –classpath %pjeeclasspath%;. CustWorkImpl.java(2)
产生Stub及Skeleton
c:\jdk1.1.8\bin\rmic -classpath %pjeeclasspath%;. CustWorkImpl(3)
编译Server端程序
c:\jdk1.1.8\bin\javac -classpath %pjeeclasspath%;. JSESocketFactory.java(4)
编译Client端程序
c:\jdk1.1.8\bin\javac -classpath %pjeeclasspath%;. RMIClient.java(5)
执行程序
注意您需要开两个DOS窗口来执行这两只程序
激活RMI Server程序 pjava -classpath %pjeeclasspath%;. JSESocketFactory(1)
图 RMI Server激活画面 激活RMI Client程序 pjava -classpath %pjeeclasspath%;. RMIClient
图 RMI Client激活画面 另外将Client端移植到WinCE中千万别忘了把XXXX_Stub档案也一起移动过去。
结论 当网络技术,配合无线网络卡,或是其它的产品,相信会是相当有趣的事情。