用RMI举办长途要领挪用
副标题#e#
长途要领挪用(RMI)机制可以把面向工具的思想进一步扩展,因为你可以挪用的工具不只可以在本机上,也可以在此外主机上。本文就简朴先容rmi的编程要领。
首先先容一些简朴的rmi的观念。
1,处事器和客户:在rmi中,假如有一个工具举办长途要领挪用,这个工具就叫做客户机工具,而长途工具则被称为处事器工具。
2,建设处事器工具的处事器措施:这个措施用来建设处事器工具,注册这个工具,使得客户可以通过注册的名称会见处事器工具。
3,接口(interface),接口可以让客户端相识处事器所能做的事情。更详细的说,就是它列出了可以在处事器上执行的所有要领。客户端措施必需可以或许找到这个类,不然就不能执行对处事器函数的挪用。
4,客户桩(stub),有的书中翻译成为代码存根,它给客户端措施提供一个桩,这个桩上"绑"着处事器工具。当客户措施需要挪用长途工具时,这个桩被下载到客户端(假如客户端有这个类,则不需要下载)。然后客户就可以像挪用当处所法一样挪用长途的要领了。
这个客户桩的浸染是将客户向处事器的请求举办编码、举办传输,处事器执行这次挪用后将功效返回到客户桩,客户桩举办解码,将解码后的功效传送到客户措施中。对付编写客户端的措施员来说,他不需要知道个中的详细进程。
客户桩不需要本身编写,后头会说明它的生成要领。它实现了前述的接口(interface)。
下面就通过一个例子来说明编写的进程。
1,编写处事器的接口:这一步是最主要的部门,因为接口是毗连客户机与处事器的要害部门。在这个例子中,接口很简朴,代码如下:
import java.rmi.*;
public interface Product extends Remote
{
String getDescription() throws RemoteException;
}
在这里应留意的是,长途工具的接口必然要扩展(extend)Java.rmi包的Remote接口。同时接口中的所有的要领都要声明抛出RemoteException异常。这是因为由于网络毗连的不行靠性,长途要领挪用很大概失败。假如不声明异常,在长途要领挪用失败后,应用措施就会无法竣事。
2,编写处事器工具:
Java中具有一个可以直接利用的处事器类–UniCastRemoteObject。它存在于Java.rmi.server包中。我们可以直接扩展这个类,使它实现前述的接口。这样就可以使处事器满意我们的需要。
import java.rmi.server.*;
import java.rmi.*;
public class ProductImpl extends UnicastRemoteObject implements Product
{
public ProductImpl(String name) throws RemoteException
{
Desc = name;
}
public String getDescription() throws RemoteException
{
return "This is "+Desc+" product";
}
private String Desc;
}
可以看到,rmi处事器的实现和其他的要领代码没有什么差异。
#p#副标题#e#
3,编写建设处事器工具的处事器措施:
import java.rmi.*;
public class ProductServer
{
public static void main(String[] args)
{
try
{
System.out.println("Constructin Server implementations ....");
ProductImpl p1 = new ProductImpl("toaster");
ProductImpl p2 = new ProductImpl("microwave");
System.out.println("Binding server implementations to registry");
Naming.rebind("toaster",p1);
Naming.rebind("microwave",p2);
System.out.println("waiting for clients...");
}catch(Exception e)
{
System.out.println("Error "+e);
}
}
}
通过代码可以看到,这个处事器首先建设了两个处事器工具。然后利用Naming.rebind()要领,将这个工具和一个名称接洽(绑定)在一起。这个名称就是客户机查找处事器工具所利用的名称。Naming是java.rmi包中的类。这个类的浸染是成立一套查找工具的定名机制。通过它就可以将绑定在特命名称上的工具找到。
4,编写客户端代码:
import java.rmi.*;
import java.rmi.server.*;
public class ProductClient
{
public static void main(String[] args)
{
System.out.println("begin to invoke remote method");
System.setSecurityManager(new RMISecurityManager());
String url = "rmi://91.1.1.119:1099/";
try
{
file://查找长途工具
System.out.println("1");
Product c1 = (Product)Naming.lookup(url + "toaster");
Product c2 = (Product)Naming.lookup(url + "microwave");
file://挪用长途要领
System.out.println("2");
System.out.println(c1.getDescription());
System.out.println("3");
System.out.println(c2.getDescription());
}catch (Exception ex)
{
System.out.println("error "+ex);
}
}
}
#p#分页标题#e#
在这段代码中,首先界说了一个字符串url。这个字符串中存储了找到长途处事器工具的协议和地点信息。在rmi中,所利用的协议是rmi,端标语是1099。这个例子中,我的处事器工具存放在ip地点为91.1.1.119的主机上,所以,这个字符串的值为rmi://91.1.1.119:1099/。
接着,利用Naming.lookup()要领查找长途工具。参数就是处事器的位置信息和处事器工具所绑定的名称。
这里需要留意的是,通过lookup要领获得其实不是处事器工具自己的引用,而是下载到客户机上的客户桩。可是,这个要领获得的是Object范例,要利用这个工具,必需将它范例转换成处事器所实现的接口范例。
随后,就可以像挪用当处所法一样挪用长途要领。在这个例子中,长途要领是getDescription()。
因为这段代码是对长途工具举办操纵,所以,它被放到一个try…catch块中,来捕捉长途挪用进程中的异常。
最后,就要将处事器和客户机陈设到呆板上。
1,将所有的类文件编译为class文件。然后在dos方法下利用
rmic ProductImpl
就可以生成客户桩,名为ProductImpl_Stub.class。
2,把客户端代码和接口代码拷贝到客户呆板上。
3,运行rmiregistry措施,启动注册系统,使得处事器可以注册在呆板上,以供客户挪用。
4,启动http处事。将接口类和客户桩类放在http处事器上,使得客户可以下载。假设这两个文件的下载目次是http://91.1.1.119/download/
5,利用start java -Djava.rmi.server.codebase= http://91.1.1.119/download/ ProductServer
运行建设处事器工具的措施。
个中的-Djava.rmi.server.codebase= http://91.1.1.119/download/ 指明客户措施下载客户桩的地点。
6,因为rmi有安详限制,所以在客户端必需成立一个计策文件。假设名为client.policy
文件的内容为
grant
{
permission java.net.SocketPermission "91.1.1.119:1024-65535","connect";
permission java.net.SocketPermission "91.1.1.119:80","connect";
};
利用 start java -Djava.security.policy=client.policy ProductClient 启动客户端,客户端就可以毗连80端口(http端口)和1024-65535的端口(个中包括了rmi的缺省端口1099)。之后就可以看到措施的执行功效。
以上就是利用rmi举办长途要领挪用的根基进程。
可是,应该留意到,rmi有一个很大的限制,那就是只能在java编写的工具之间利用,假如要在差异的语言写成的工具之间通讯,那就需要CORBA的辅佐