加入收藏 | 设为首页 | 会员中心 | 我要投稿 汽车网 (https://www.0577qiche.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

如何理解Java 中的RMI-IIOP

发布时间:2023-04-21 15:37:58 所属栏目:教程 来源:
导读:测试代码的JDK版本在文中会具体说明,有的代码会被重复使用,对应的JDK版本需要自己切换

Java IDL是一种用于分布式对象的技术,即对象在网络上的不同平台上进行交互。Java IDL使对象能够进行交互,而不管它们是以
测试代码的JDK版本在文中会具体说明,有的代码会被重复使用,对应的JDK版本需要自己切换

Java IDL是一种用于分布式对象的技术,即对象在网络上的不同平台上进行交互。Java IDL使对象能够进行交互,而不管它们是以Java编程语言还是C,C ++,COBOL或其他语言编写的。这是可能的,因为Java IDL基于通用对象请求代理体系结构(CORBA),即行业标准的分布式对象模型。CORBA的主要功能是IDL,一种与语言无关的接口定义语言。每种支持CORBA的语言都有自己的IDL映射-顾名思义,Java IDL支持Java映射。为了支持单独程序中对象之间的交互,Java IDL提供了一个对象请求代理或ORB(Object Request broker)。ORB是一个类库,可在Java IDL应用程序与其他符合CORBA的应用程序之间进行低层级的通信。

CORBA,Common ObjectRequest broker Architecture(公共对象请求代理体系结构),是由OMG组织制订的一种标准的面向对象应用程序体系规范。CORBA使用接口定义语言(IDL),用于指定对象提供给外部的接口。然后,CORBA指定从IDL到特定实现语言(如Java)的映射。CORBA规范规定应有一个对象请求代理(ORB),通过该对象应用程序与其他对象进行交互。通用InterORB协议(GIOP)摘要协议的创建是为了允许ORB间的通信,并提供了几种具体的协议,包括Internet InterORB协议(IIOP),它是GIOP的实现,可用于Internet,并提供GIOP消息和TCP/IP层之间的映射。

IIOP,Internet Inter-ORB Protocol(互联网内部对象请求代理协议),它是一个用于CORBA 2.0及兼容平台上的协议;用来在CORBA对象请求代理之间交流的协议。Java中使得程序可以和其他语言的CORBA实现互操作性的协议。

RMI-IIOP出现以前,只有RMI和CORBA两种选择来进行分布式程序设计,二者之间不能协作。RMI-IIOP综合了RMI 和CORBA的优点,克服了他们的缺点,使得程序员能更方便的编写分布式程序设计,实现分布式计算。RMI-IIOP综合了RMI的简单性和CORBA的多语言性兼容性,RMI-IIOP克服了RMI只能用于Java的缺点和CORBA的复杂性(可以不用掌握IDL)。

CORBA-IIOP远程调用
在CORBA客户端和服务器之间进行远程调用模型如下:

如何理解Java 中的RMI-IIOP

在客户端,应用程序包含远程对象的引用,对象引用具有存根方法,存根方法是远程调用该方法的替身。存根实际上是连接到ORB的,因此调用它会调用ORB的连接功能,该功能会将调用转发到服务器。

在服务器端,ORB使用框架代码将远程调用转换为对本地对象的方法调用。框架将调用和任何参数转换为其特定于实现的格式,并调用客户端想要调用的方法。方法返回时,框架代码将转换结果或错误,然后通过ORB将其发送回客户端。

在ORB之间,通信通过共享协议IIOP进行。基于标准TCP/IP Internet协议的IIOP定义了兼容CORBA的ORB如何来回传递信息。

编写一个Java CORBA IIOP远程调用步骤:

使用idl定义远程接口

使用idlj编译idl,将idl映射为Java,它将生成接口的Java版本类以及存根和骨架的类代码文件,这些文件使应用程序可以挂接到ORB。在远程调用的客户端与服务端编写代码中会使用到这些类文件。

编写服务端代码

编写客户端代码

依次启动命名服务->服务端->客户端

好了,用代码感受下( github找到一份现成的代码可以直接用,不过做了一些修改):

1、2步骤作者已经帮我们生成好了,生成的代码在 EchoApp目录

服务端:

//服务端package com.longofo.corba.example;import com.longofo.corba.example.EchoApp.Echo;import com.longofo.corba.example.EchoApp.EchoHelper;import org.omg.CORBA.ORB;import org.omg.CosNaming.NameComponent;import org.omg.CosNaming.NamingContextExt;import org.omg.CosNaming.NamingContextExtHelper;import org.omg.PortableServer.POA;import org.omg.PortableServer.POAHelper;public class Server {
    public static void main(String[] args) {
        if (args.length == 0) {
            args = new String[4];
            args[0] = "-ORBInitialPort";
            args[1] = "1050";
            args[2] = "-ORBInitialHost";
            args[3] = "localhost";
        }
        try {
            //创建并初始化ORB            ORB orb = ORB.init(args, null);
            //获取根POA的引用并激活POAManager            POA rootpoa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
            rootpoa.the_POAManager().activate();
            //创建servant            EchoImpl echoImpl = new EchoImpl();
            //获取与servant关联的对象引用            org.omg.CORBA.Object ref = rootpoa.servant_to_reference(echoImpl);
            Echo echoRef = EchoHelper.narrow(ref);
            //为所有CORBA ORB定义字符串"NameService"。当传递该字符串时,ORB返回一个命名上下文对象,该对象是名称服务的对象引用            org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
            NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
            NameComponent path[] = ncRef.to_name("ECHO-SERVER");
            ncRef.rebind(path, echoRef);
            System.out.println("Server ready and waiting...");
            //等待客户端调用            orb.run();
        } catch (Exception ex) {
            ex.printstacktrace();
        }
    }}
客户端:

//客户端package com.longofo.corba.example;import com.longofo.corba.example.EchoApp.Echo;import com.longofo.corba.example.EchoApp.EchoHelper;import org.omg.CORBA.ORB;import org.omg.CosNaming.NamingContextExt;import org.omg.CosNaming.NamingContextExtHelper;public class Client {
    public static void main(String[] args) {
        if (args.length == 0) {
            args = new String[4];
            args[0] = "-ORBInitialPort";
            args[1] = "1050";
            args[2] = "-ORBInitialHost";
            args[3] = "localhost";
        }
        try {
            //创建并初始化ORB            ORB orb = ORB.init(args, null);
            org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
            NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
            Echo href = EchoHelper.narrow(ncRef.resolve_str("ECHO-SERVER"));
            String hello = href.echoString();
            System.out.println(hello);
        } catch (Exception ex) {
            ex.printstacktrace();
        }
    }}//使用Jndi查询客户端package com.longofo.corba.example;import com.alibaba.fastjson.JSON;import com.longofo.corba.example.EchoApp.Echo;import com.longofo.corba.example.EchoApp.EchoHelper;import javax.naming.*;import java.io.IOException;import java.util.HashMap;import java.util.Hashtable;import java.util.Map;public class JndiClient {
    /**
     * 列出所有远程对象名
     */
    public final static String JNDI_FACTORY = "com.sun.jndi.cosnaming.CNCtxFactory";
    public static void main(String[] args) throws NamingException, IOException, ClassNotFoundException {
        InitialContext initialContext = getinitialContext("iiop://127.0.0.1:1050");
        //列出所有远程对象名        System.out.println(JSON.toJSONString(listAllEntries(initialContext), true));
        System.out.println("-----------call remote method--------------");
        Echo echoRef = EchoHelper.narrow((org.omg.CORBA.Object) initialContext.lookup("ECHO-SERVER"));
        System.out.println(echoRef.echoString());
    }
    private static Map listAllEntries(Context initialContext) throws NamingException {
        String namespace = initialContext instanceof InitialContext ? initialContext.getNameInNamespace() : "";
        HashMap<String, Object> map = new HashMap<String, Object>();
        System.out.println("> Listing namespace: " + namespace);
        NamingEnumeration<NameClasspair> list = initialContext.list(namespace);
        while (list.hasMoreElements()) {
            NameClasspair next = list.next();
            String name = next.getName();
            String jndiPath = namespace + name;
            HashMap<String, Object> lookup = new HashMap<String, Object>();
            try {
                System.out.println("> Looking up name: " + jndiPath);
                Object tmp = initialContext.lookup(jndiPath);
                if (tmp instanceof Context) {
                    lookup.put("class", tmp.getClass());
                    lookup.put("interfaces", tmp.getClass().getInterfaces());
                    Map<String, Object> entries = listAllEntries((Context) tmp);
                    for (Map.Entry<String, Object> entry : entries.entrySet()) {
                        String key = entry.getKey();
                        if (key != null) {
                            lookup.put(key, entries.get(key));
                            break;
                        }
                    }
                } else {
                    lookup.put("class", tmp.getClass());
                    lookup.put("interfaces", tmp.getClass().getInterfaces());
                }
            } catch (Throwable t) {
                lookup.put("error msg", t.toString());
                Object tmp = initialContext.lookup(jndiPath);
                lookup.put("class", tmp.getClass());
                lookup.put("interfaces", tmp.getClass().getInterfaces());
            }
            map.put(name, lookup);
        }
        return map;
    }
    private static InitialContext getinitialContext(String url) throws NamingException {
        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
        env.put(Context.PROVIDER_URL, url);
        return new InitialContext(env);
    }}

(编辑:汽车网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章