XMLRPC++学习笔记

1   参数类型 XmlRpcValue
    标量数据类型(scalar )
  参数值<value>可以是标量,用类型标签将值包括起来。如果没指定类型,则认为是string类型。
   <i4>或者 <int>表示 4字节带符号整数值   
   <boolean>表示 0 (false) or 1 (true)   
   <string>表示     字符串   
   <double>表示     双精度带符号浮点值   
   <dateTime.iso8601>表示 日期/时间
   <base64>表示 base64编码的二进制数据

 结构数据类型(<struct>)
  参数值也可以是<struct>类型一个<struct>可含有几个<member>项,每个< member>含有一个<name>项和一个<value>项。<member>的< value>值可以为任何类型,可为标量类型、<array>甚至<struct>(即可以递归).


  数组数据类型(<array>)
  参数值也可以是<array>类型一个<array>含有单一的 <data> 元素,<data>元素可以含有任意数量的<value>, 这里的<value>没有name.每个<value>的数据类型可各不相同,如下例所示。
  <data>的<value>值可以为任何类型,可为标量类型、 <struct>甚至<array>(即可以递归).

(例子可参见:http://hedong.3322.org/archives/000470.html)

XMLRPC++代码中与此对应的是类 XmlRpc::XmlRpcValue
类型定义如下:
enum Type {
       TypeInvalid,// 非法类型
       TypeBoolean,// 0 (false) or 1 (true)
       TypeInt,// 4字节带符号整数值
       TypeDouble,// 双精度带符号浮点值   
       TypeString,// 字符串   
       TypeDateTime,// 日期/时间
       TypeBase64,// base64编码的二进制数据
       TypeArray, // 数组数据类型
       TypeStruct // 结构数据类型
     };
     typedef std::vector<char> BinaryData; // 二进制数据
     typedef std::vector<XmlRpcValue> ValueArray; // 数组
     typedef std::map<std::string, XmlRpcValue> ValueStruct;// 结构

一个  XmlRpcValue 对象只能有一个值,通过一个联合来定义,如下:
union {
   bool   asBool
   int   asInt
   double   asDouble
   tm *   asTime
   std::string *   asString
   BinaryData *   asBinary
   ValueArray *   asArray
   ValueStruct *   asStruct
} _value;

类XmlRpcValue提供的方法包括如下几类:
a 从xml中获得数据,如boolFromXml,intFromXml,doubleFromXml等
b 将数据转换成xml格式,如boolToXml,intToXml,doubleToXml等(继承自 XmlRpcSource):
c 类型检查,如assertArray,assertStruct等
d 操作符重载,如赋值=,==,!=等,若为数组,则可使用 [] 提取指定元素
e 其他

XMLRPC 执行远程调用时,其输入参数与执行结果均封装在  XmlRpcValue 对象中。
执行顺序如下:
客户端 将需执行的方法,以及方法参数(XmlRpcValue)以XML格式(通过HTTP协议)传输到服务器端,服务器解析XML,获得以XmlRpcValue封装的参数,在服务器端调用方法,获得以 XmlRpcValue封装的执行结果,将其以XML格式传输至客户端,客户端解析,获得执行结果(XmlRpcValue)。
也就是说,所有的数据都是 通过 XmlRpcValue 格式 进行 交互。
参数:
客户端  参数 -> XmlRpcValue params-> XML -> HTTP协议传输 -> XML ->XmlRpcValue params->服务器端  参数
执行结果:
服务器端 执行结果 -> XmlRpcValue result-> XML -> HTTP协议传输 -> XML ->XmlRpcValue result->客户端  执行结果

2  服务器支持的调用方法的基类 XmlRpc::XmlRpcServerMethod
    所有服务器支持的方法必须继承自 XmlRpcServerMethod
   包含两个字段:
  std::string     _name      方法名称
  XmlRpcServer *     _server 服务器
  
   构造函数为XmlRpcServerMethod(std::string const& name, XmlRpcServer* server),其中有一句:
    if (_server) _server->addMethod(this);
   这句是方法向服务器注册本身。  
 
    执行的关键则在于其一个纯虚函数:
  virtual void     execute (XmlRpcValue &params, XmlRpcValue &result)=0
    调用方法的实现过程 就在这个函数内实现。
    输入参数为 params,从客户端读取而获得;执行结果 放入 result,执行完毕后返回给客户端。
 
    例子:
 
#include  " XmlRpc.h "
using   namespace  XmlRpc;

//  The server
XmlRpcServer s;

//  The Hello method. No arguments, result is "Hello".
class  Hello :  public  XmlRpcServerMethod
{
public:
  Hello(XmlRpcServer
* s) : XmlRpcServerMethod("Hello", s) {}

  
void execute(XmlRpcValue& params, XmlRpcValue& result)
  
{
    result 
= "Hello";
  }


}
 hello( & s);     //  This constructor registers the method with the server

 
3  RPC处理的端点 RpcSource:An RPC source represents a file descriptor to monitor
        这个类是服务器与客户端的基类。可以这样理解,一个 RpcSource 就表示一个  Socket 连接。
   RpcSource 包括三个私有成员:
    int _fd;               socket file descriptor to monitor,socket连接
    bool _deleteOnClose;   当连接关闭时,是否删除本身
    bool _keepOpen;        In the client, keep connections open if you intend to make multiple calls.
       关键函数:
    virtual unsigned handleEvent(unsigned eventType) = 0;
      
 
4  RPC客户端 XmlRpc::XmlRpcClient(继承自 XmlRpcSource):发送请求至服务器端,并读取分析服务器的 响应
        客户端有六个状态分别为:NO_CONNECTION, CONNECTING, WRITE_REQUEST, READ_HEADER, READ_RESPONSE, IDLE
 
          构造函数XmlRpcClient(const char* host, int port, const char* uri=0);
          参数 host表示服务器端地址,port表示端口号,uri是http请求头的可选串;  构造函数将客户状态设置为:NO_CONNECTION
         
          关键函数:
    bool XmlRpcClient::execute(const char* method, XmlRpcValue const& params, XmlRpcValue& result)
          在服务器端执行以method名称指定的方法;方法参数 params,执行结果 result
          (调用其他函数  setupConnection  generateRequest  XmlRpcDispatch.work parseResponse 实现功能 )        
 
    unsigned XmlRpcClient::handleEvent(unsigned eventType)
          处理服务器的响应。该方法在 XmlRpcDispatch 被调用。
        (调用其他函数  writeRequest  readHeader  readResponse 实现功能 )   

    setupConnection,writeRequest,readHeader,readResponse等函数中依次修改 客户的状态。
       
5  RPC服务器XmlRpc::XmlRpcServer(继承自 XmlRpcSource):处理客户请求
     
        该类只监听客户的连接请求,而不处理其调用函数的请求。函数  bindAndListen 将服务器绑定至指定的端口并准备开始监听。
        
        函数 void XmlRpcServer::work(double msTime) 在指定的时间msTime内处理用户请求
   work 调用  XmlRpcDispatch.work 开始工作,XmlRpcDispatch.work 调用 XmlRpcServer.handleEvent 接受用户请求。
        真正接受用户请求的代码在 acceptConnection 中,被 handleEvent 调用。
        每有一个用户连接请求到来,都会执行 acceptConnection函数 accpet之后的代码,创建一个新的 XmlRpcServerConnection。
       每一个 XmlRpcServerConnection 都为一个单独的客户进行服务:接受请求,在服务器端执行代码(XmlRpcDispatch.work),并产生响应。
 
  XmlRpcServer对象维护所支持的调用方法列表,以<方法名,方法对象*>格式,其定义如下:
  typedef std::map< std::string, XmlRpcServerMethod* > MethodMap;即方法名于方法对象的映射
  MethodMap _methods;
    
  XmlRpcServer对象维护事件分发器对象  XmlRpcDispatch _disp;
     各方法真正执行在 _disp.work() 被调用执行。
 
6 RPC服务器 连接类 XmlRpcServerConnection(继承自 XmlRpcSource):每一个客户均与一个 XmlRpcServerConnection 对象对应,并为其服务
     该类有四个状态分别为: READ_HEADER, READ_REQUEST, WRITE_RESPONSE
    
  unsigned  XmlRpcServerConnection::handleEvent(unsigned /*eventType*/)
      接受客户请求,并在服务器端执行请求的方法,并将执行结果返回
 
 7 XmlRpc::XmlRpcDispatch
     这个类理解有些模糊。感觉像把所有的事情集中起来,然后放在一起处理。
    该类维护一个当前被监视的对象列表 typedef std::list< MonitoredSource > SourceList;
    每一个被监视的对象定义为:
  struct MonitoredSource {
      XmlRpcSource* _src;
      unsigned _mask;
    };
 
  其核心这个方法:
void  XmlRpcDispatch::work( double  timeout)
 
{
     ……
     
//顺序遍历所有源,并处理每个源的方法handleEvent
  for (it=_sources.begin(); it != _sources.end(); )
    
{
      SourceList::iterator thisIt 
= it++;
      XmlRpcSource
* src = thisIt->getSource();
      
int fd = src->getfd();
      unsigned newMask 
= (unsigned) -1;
      
if (fd <= maxFd) {
        
if (FD_ISSET(fd, &inFd))
          newMask 
&= src->handleEvent(ReadableEvent);
        
if (FD_ISSET(fd, &outFd))
          newMask 
&= src->handleEvent(WritableEvent);
        
if (FD_ISSET(fd, &excFd))
          newMask 
&= src->handleEvent(Exception);
                }
      ……
      }


参考 :http://xmlrpcpp.sourceforge.net/
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值