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 ¶ms, 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/
标量数据类型(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 ¶ms, XmlRpcValue &result)=0
调用方法的实现过程 就在这个函数内实现。
输入参数为 params,从客户端读取而获得;执行结果 放入 result,执行完毕后返回给客户端。
例子:






















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;
};
其核心这个方法:























参考 :http://xmlrpcpp.sourceforge.net/