????? 远程调用对一些不需要实时数据的地方可以考虑用WebService或者xmlrpc,而不采用socket,比如获取配置项信息等. 最近和我同事商讨,总结了一套可以应付各种需求的远程调用方法,并且实现了。好东西,大家共分享:
?
???
web service报文协议
描述
采用xml格式进行数据交互
协议
请求报文
<?xml version="1.0" encoding = "UTF-8"?>
<aot>
?????? <method>tribe.gettribe</method>
?????? <callid></callid>
<token>123456789</token>
?????? <param>
????????????? <p>60000018</p>
????????????? <p>fantaotao</p>
?????? </param>
</aot>
?
字段 |
含义 |
说明 |
aot |
xml根节点 |
? |
method |
远过程名 |
? |
callid |
调用标识 |
1.?????? 值可为空 2.?????? web端必须原样返回该字段值 |
token |
登录令牌 |
1.?????? 值可为空(在TATA未登时可为空) 2.?????? TATA登录后会取得该令牌 |
param |
参数集 |
3.?????? 没有参数,该结点可没有 4.?????? 该节点下的子节点,都用来描述具体的参数内容 5.?????? 参数必须保证顺序 |
p |
描述具体某个参数 |
1.? 参数必须保证顺序 |
?
应答报文
<?xml version="1.0" encoding = "UTF-8"?>
<aot>
?????? <ret>0</ret>
?????? <msg>操作成功</msg>
??? <callid>调用标识</callid>
<token>登录令牌为GUID</token>
?????? <recordset>
????????????? <recordcount>记录总数</recordcount>
????????????? <pagesize>一页显示记录数</pagesize>
????????????? <record>
???????????????????? <id>1001</id>
???????????????????? <name>黑手党</name>
???????????????????? <members>200<members>
????????????? </record>
????????????? <record>
???????????????????? <id>1002</id>
???????????????????? <name>美女群</name>
???????????????????? <members>120<members>
????????????? </record>
?????? </recordset>
</aot>
?
字段 |
含义 |
说明 |
aot |
xml根节点 |
? |
ret |
操作结果(数字) |
1.?????? =0: 操作成功 2.?????? !=0: 失败,msg字段描述具体失败原因 |
msg |
操作结果描述 |
可为空,描述具体操作的结果信息 |
callid |
调用标识 |
1. 原样返回请求报文中的callid字段 |
recordset |
记录集 |
1.?????? 返回的操作结果集 2.?????? 可为空 |
recordcount |
记录总数 |
可为空 |
recordsize |
一页显示记录数 |
可为空 |
record |
表示一个记录 |
? |
?
C++ 接口设计:
?
?
??? class ipacket;
??? class ievent_handler
??? {
??? public:
??????? virtual void on_recv(ipacket* _pack) = 0;
??? };
?
??? class ipacket : public aot::tt::interface_base
??? {
??? protected:
??????? virtual ~ipacket(){;}?
??? public:
??????? virtual bool query_interface(void** out,const char* key){return false;}
??????? virtual const char* interface_name(){return "ipacket";}?
??? public:
??????? virtual void set_event_handler(ievent_handler* pHandler) = 0;
??????? virtual ievent_handler* get_event_handler() = 0;
??? public:?
??????? //参数操作
??????? virtual void set_method(const char* method) = 0;
??????? virtual void set_call_id(const char* call_id) = 0;
??????? virtual void set_token(const char* token) = 0;
??????? virtual void push_back(const char* key,const char* value) = 0;
????????
??????? virtual bool get_params(aot::tt::istr** out) = 0; // 获取发出去的参数报文
??? public:
??????? // 结果操作
??????? virtual int get_ret_code() = 0;?? //WebService调用结果,1 成功 其他失败
??????? virtual void set_result(const char* result) = 0; // 设置原始的返回报文并且解析
??????? virtual bool get_result(aot::tt::istr** out) = 0; // 获取返回的原始的报文
???????
??????? virtual bool is_valid() = 0; //返回的xml是否有效
??????? virtual int? get_ret_result_code() = 0; // 返回的报文中的ret 值
??????? virtual bool get_ret_result_msg(aot::tt::istr** out) = 0; //返回的报文中的msg 值
??????? /************************ recordset op ******************/
??????? /************************ begin *************************/
??????? //必须先调用get_recordset_count,然后才可调用其它recordset操作函数
??????? virtual long get_recordset_count() = 0;
??????? virtual bool goto_first_recordset() = 0;
??????? virtual bool goto_next_recordset() = 0;
??????? virtual bool goto_recordset(int n=1) = 0;
??????? virtual int? get_recordset_recordcount() = 0;? // 获取recordset 报文 中的 recordcount
??????? virtual int? get_recordset_pagesize() = 0;??? // 获取recordset 报文 中的 pagesize
??????? /************************ recordset op ******************/
??????? /************************ end *************************/
??????? /************************ record op *********************/
??????? /************************ begin *************************/
??????? //必须先调用get_record_count,然后才可调用其它record操作函数
??????? virtual long get_record_count() = 0;
??????? virtual bool goto_first_record() = 0;
??????? virtual bool goto_next_record() = 0;
??????? virtual bool goto_record(int n=1) = 0;
??????? virtual bool get_record_raw_str(aot::tt::istr** out) = 0; //获取record的原始报文
??????? virtual bool get_value(const char* key,aot::tt::istr** out,const char* default="") = 0;
??????? virtual int get_value_int(const char* key,int default = 0) = 0;
??????? /************************ record op *********************/
??????? /************************ end ***************************/
???????
???????
??? };
???
??? class iwebRpc : public aot::tt::interface_base
??? {
??? protected:
??????? virtual ~iwebRpc(){;}?
??? public:
??????? virtual bool query_interface(void** out,const char* key){return false;}
??????? virtual const char* interface_name(){return "iwebRpc";}?
??? public:
??????? virtual bool set_root_url(const char* szUrl) = 0;
???????
??????? /************************ 通用WebService处理 *********************/
??????? virtual bool sy_post_packet(ipacket* _pack) = 0;
??????? /*??????????? pPack 必须绑定一个 ievent_handler 的事件处理器,并且必须在事件处理中把pPack 释放掉??????? */??????? virtual bool asy_post_packet(ipacket* pPack) = 0;???? ??????? /************************ 通用WebService处理 结束 *********************/??? };