ICE的同步动态调用

1、ICE环境下基于slice上的proxy方法调用是传统的静态RPC调用方式,ICE提供了另外一种动态的调用方式,可以不依赖于
   具体的slice接口定义,具体接口如下:
   bool ice_invoke(const std::string& operation, Ice::OperationMode mode, const std::vector< Ice::Byte >& inParams,
                   std::vector< Ice::Byte >& outParams);
   一个完整的调用样例如下:
   Ice::ObjectPrx proxy = ...;                // 获取代理对象
   try {
       std::vector< Ice::Byte > inParams, outParams;
       Ice::OutputStreamPtr out = Ice::createOutputStream(communicator);
       out->writeInt(100); // x
       out->writeInt(-1); // y
       out->finished(inParams);              // 流式化输入参数


       // 动态调用,调用成功返回true,调用失败返回false
       if (proxy->ice_invoke("add", Ice::Idempotent, inParams, outParams)) {
           // Handle success
           Ice::InputStreamPtr in = Ice::createInputStream(communicator, outParams);
           int result = in->readInt();       // 获取返回结果
       } else {
           Ice::InputStreamPtr in = Ice::createInputStream(communicator, outParams);
           try {
               in->throwException();         // 从输出流中获取异常
           } catch (const Calc::Overflow& ex) {
               cout << "overflow while adding " << ex.x << " and " << ex.y << endl;
           } catch (const Ice::UserException& ex) {
               // Handle unexpected user exception
           }
       }   
    }
2、服务器端的调用支持动态的分发,也可以不依赖于具体的slice文件写入Servant的接口实现:
    class ComputeI : public Ice::Blobject 
    {
    public:
        virtual bool ice_invoke(const std::vector& inParams, std::vector& outParams,
                                const Ice::Current& current)
        {
            if (current.operation == "add") {            // 判断操作类型
            {
                Ice::CommunicatorPtr communicator = current.adapter->getCommunicator();
                Ice::InputStreamPtr in = Ice::createInputStream(communicator, inParams);
                int x = in->readInt();                   // 获取输入参数
                int y = in->readInt();
                
Ice::OutputStreamPtr out = Ice::createOutputStream(communicator);
                if (checkOverflow(x, y)) {
                    Calc::Overflow ex;                  // 调用失败记录异常
                    ex.x = x;
                    ex.y = y;
                    out->writeException(ex);
                    out->finished(outParams);
                    return false;
                } else {
                    out->writeInt(x + y);               // 正常操作写入结果
                    out->finished(outParams);
                    return true;
                }
            } else {
                Ice::OperationNotExistException ex(__FILE__, __LINE__);
                ex.id = current.id;                     // 不支持的操作
                ex.facet = current.facet;
                ex.operation = current.operation;
                throw ex;
            }
        }
    };
3、往往为了从效率的角度考虑,最好使用减少一次拷贝的ice_invoke方法原型:
   bool ice_invoke(const std::string& operation, Ice::OperationMode mode, const std::pair< const Ice::Byte*, const Ice::Byte* >& in,
                   std::vector< Ice::Byte >& out);         // 客户端通过该方法调用
   class BlobjectArray                                     // 服务器端从该类继承,并实现如下虚方法
   {
    public:
        virtual bool ice_invoke(const std::pair& in, std::vector& out,
                                const Ice::Current& current) = 0;
};    

你可能感兴趣的:(ICE学习)