`
splayx
  • 浏览: 82846 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

ICE远程函数调用

    博客分类:
  • ICE
 
阅读更多

用ICE框架可以很容易地实现远程函数调用,广泛使用在分布式系统中。

ICE框架由客户端和服务器组成,支持客户端并发地调用服务器的服务。默认是一个同步调用。可以改成异步调用。

 

下面给出一个简单的例子。实现客户端和服务器间的一问一答。

 

服务器部分:

 

服务器做的工作稍微多点,首先我们需要定义一个ice文件,包含我们需要的接口。

 

IM.ice

#ifndef IM_ICE
#define IM_ICE

module IM {
    interface IMInterface {
        int SendMsg(
                string req,
                out string rsp);
    };
};

#endif
 

然后使用slice2cpp这个bin生成IM.h和IM.cpp,

slice2cpp IM.ice

 

自己写一个类IMInterfaceI继承IMInterface,并实现SendMsg这个方法。

SendMsg在IMInterface中是一个纯虚函数,必须在IMInterfaceI中实现。

 

IMInterfaceI.h

#ifndef __IM_INTERFACE_I_H__
#define __IM_INTERFACE_I_H__

#include "IM.h"

using namespace IM;

class IMInterfaceI : public IMInterface {
    ::Ice::Int SendMsg(const ::std::string&, ::std::string&, const ::Ice::Current& = ::Ice::Current());
};

#endif

 IMInterfaceI.cpp

#include "IMInterfaceI.h"

#include <iostream>

using namespace std;

::Ice::Int IMInterfaceI::SendMsg(const ::std::string& req, ::std::string& rsp, const ::Ice::Current&) {
    cout << req << endl;
    getline(cin, rsp);
    return 0;
}

 这样我们就可以启动这个服务了,让客户端来调用SendMsg这个接口。

Server.cpp

#include <Ice/Ice.h>
#include "IMInterfaceI.h"

using namespace std;

int main(int argc, char** argv) {
    int status = 0;
    Ice::CommunicatorPtr ic;
    try {
        ic = Ice::initialize(argc, argv);
        Ice::ObjectAdapterPtr adapter =
            ic->createObjectAdapterWithEndpoints("IM", "default -p 9999");
        //IMInterfaceI是由ice文件生成的类派生出来的
        Ice::ObjectPtr object = new IMInterfaceI();
        //"IMInterface"是我们这个实例的标志符
        //以后提供给客户端的连接串就是"IMInterface:default -p 9999"
        //default = tcp -h 127.0.0.1,可以显式表达
        adapter->add(object, ic->stringToIdentity("IMInterface"));
        adapter->activate();
        ic->waitForShutdown();
    } catch (const Ice::Exception& e) {
        cerr << e << endl;
        status = 1;
    } catch (const char* msg) {
        cerr << msg << endl;
        status = 1;
    }
    if (ic) {
        try {
            ic->destroy();
        } catch (const Ice::Exception& e) {
            cerr << e << endl;
            status = 1;
        }
    }
    return status;
}
 

最后编译连接,这个服务就可以用了。

 

c++ -I. -I$ICE_HOME/include -c IM.cpp IMInterfaceI.cpp Server.cpp

echo ".o generated successfully!\n"

c++ -o Server IM.o IMInterfaceI.o Server.o -L$ICE_HOME/lib -lIce -lIceUtil

echo ".o linked successfully!\n"

 

 

客户端部分:

将Server的ice文件拷过来,用slice2cpp这个bin生成IM.h和IM.cpp

然后就可以调用了。

#include "IM.h"

#include <Ice/Ice.h>
#include <iostream>
#include <cstring>

using namespace std;
using namespace IM;

int main(int argc, char** argv) {
    int status = 0;
    Ice::CommunicatorPtr ic;
    try {
        ic = Ice::initialize(argc, argv);
        //"IMInterface:default -p 9999"是服务器提供的连接串
        Ice::ObjectPrx base = ic->stringToProxy("IMInterface:default -p 9999");
        IMInterfacePrx ptr = IMInterfacePrx::checkedCast(base);
        if (!ptr)
            throw "Invalid proxy";

        string req, rsp;
        while (getline(cin, req)) {
            ptr->SendMsg(req, rsp);
            cout << rsp << endl;
        }
    } catch (const Ice::Exception& ex) {
        cerr << ex << endl;
        status = 1;
    } catch (const char* msg) {
        cerr << msg << endl;
        status = 1;
    }
    if (ic)
        ic->destroy();
    return status;
}

 

客户端的编译生成可执行文件的脚本。从脚本可以清晰地看到3个步骤。

1.slice2cpp生成一些.h,.cpp文件

2.编译出.o文件

3.连接.o文件形成可执行文件Client

 

ICE_HOME=/opt/ICE

slice2cpp IM.ice

c++ -I. -I$ICE_HOME/include -c IM.cpp Client.cpp

c++ -o Client IM.o Client.o -L$ICE_HOME/lib -lIce -lIceUtil

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics