hessiancpp编译与使用

从官网下的hessiancpp源码一直无法编译通过,后来索性放弃了自带的代理,使用另一个第三方开源库libcurl重写了一个代理,编译通过,可用且性能比较满意
 
1、提取hessiancpp中需要的文件
提取其中的如下文件:
exceptions.h
input_stream.h
hessian_input.h / cpp
hessian_output.h / cpp
string_input_stream.h / cpp
wrappers.h / cpp
为了方便管理,*.h放入文件夹include, *.cpp放入source
2、编译libcurl
从官网下载libcurl的源码包(最上面的Source Archives):http://curl.haxx.se/download.html
这个打开应该有2个项目,只编译libcurl,我没有遇到问题,直接编译通过
提取需要的文件:
找到include\curl,将所有的.h文件复制到上面的include文件夹
编译生成的dll和lib在 \lib\DLL-Release下libcurl_imp.lib和libcurl.dll
3、建立工程
新建一个空的控制台工程hessiancpp_test,将include、source和libcurl_imp.lib、libcurl.dll复制到工程目录
把.\include加入到附加包含目录,libcurl_imp.lib加入附加依赖项(或者源文件中加#pragma comment(lib, "libcurl_imp.lib"))
还有必须把source中的.cpp文件加入工程
编译的时候可能提示找不到inttypes.h,去google下一个或自己写一个放入include文件夹,内容如下:
 1 #ifndef __INTTYPES_H_ 
 2 #define __INTTYPES_H_ 
 3         
 4 typedef signed char int8_t; 
 5 typedef unsigned char uint8_t; 
 6 
 7 typedef int int16_t; 
 8 typedef unsigned int uint16_t; 
 9 
10 typedef long int32_t; 
11 typedef unsigned long uint32_t; 
12     
13 typedef long long int64_t; 
14 typedef unsigned long long uint64_t; 
15 
16 typedef int16_t intptr_t; 
17 typedef uint16_t uintptr_t; 
18     
19 #endif
如果是Linux下就:
 1 #include <sys/types.h> 
 2 
 3 #ifndef __INTTYPES_H_ 
 4 #define __INTTYPES_H_ 
 5         
 6 typedef signed char int8_t; 
 7 typedef unsigned char uint8_t; 
 8 
 9 typedef short int int16_t; 
10 typedef unsigned short int uint16_t; 
11 
12 typedef long long int64_t; 
13 typedef unsigned long long uint64_t; 
14 
15 typedef int intptr_t; 
16 typedef unsigned int uintptr_t; 
17     
18 #endif

然后就可以编写我们自己的代理hessian_proxy,直接上代码:

hessian_proxy.h:

 1 #pragma once 
 2 
 3 #include "hessian_input.h" 
 4 #include "hessian_output.h" 
 5 #include "input_stream.h" 
 6 #include "string_input_stream.h" 
 7 #include "wrappers.h" 
 8 #include "curl.h" 
 9 using namespace std; 
10 using namespace hessian; 
11 using namespace hessian::wrappers; 
12 
13 #pragma comment(lib, "libcurl_imp.lib") 
14 
15 #ifdef UNICODE 
16 #define ONE_CHAR_BYTE_NUM 2 
17 #else 
18 #define ONE_CHAR_BYTE_NUM 1 
19 #endif 
20 
21 class hessian_proxy 
22 { 
23 public: 
24   hessian_proxy(const string& url); 
25 public: 
26   ~hessian_proxy(void); 
27     
28 public: 
29   Object* call(const string& method, int argc, ... ); 
30   string get_ip() const;                                //返回主机地址 
31   string get_url() const;                                //返回url 
32   long get_port() const;                                  //返回端口号 
33   double bytes_upload();                                //返回发出的总字节数 
34   double bytes_download();                              //返回收到的总字节数 
35   string get_error_info(); 
36   static long num_calls();                              //返回呼叫次数 
37   static size_t write_data(void *buffer, size_t size, size_t nmemb, void *stream);  //curl处理接受数据的回调函数 
38   void inline set_share_handle();                            //设置共享对象 
39 
40   //static map<string, unsigned int>& call_size_map(); 
41 
42 private: 
43   string    _url; 
44   CURL    *_curl; 
45   CURLcode  _res; 
46     
47   curl_slist *_http_headers; 
48 
49   static CURLSH    *_share_handle; 
50   static string    _http_result; 
51   static unsigned int  _num_calls; 
52 
53   bool  _swap_OK; 
54   bool  _is_exception; 
55   char  error_buf[1024]; 
56   string  _str_exception; 
57 
58   //static map<string, unsigned int> _call_size_map; 
59 };

hessian_proxy.cpp:

  1 #include "hessian_proxy.h" 
  2 
  3 unsigned int hessian_proxy::_num_calls = 0; 
  4 CURLSH* hessian_proxy::_share_handle = NULL; 
  5 string hessian_proxy:: _http_result; 
  6 
  7 hessian_proxy::hessian_proxy(const string& url) 
  8 { 
  9   _url = url; 
 10   curl_global_init(CURL_GLOBAL_DEFAULT);  //初始化libcurl需要的环境 
 11   _curl = curl_easy_init();        //初始化一个 libcurl easy 句柄 
 12   if (!_curl) 
 13   { 
 14     printf("error handle\n"); 
 15     return; 
 16   } 
 17   set_share_handle( ); 
 18   _http_headers = NULL; 
 19   //设置http头 
 20   _http_headers = curl_slist_append(_http_headers, "Content-Type:application/x-hessian"); 
 21   curl_easy_setopt(_curl, CURLOPT_HTTPHEADER, _http_headers); 
 22   curl_easy_setopt(_curl, CURLOPT_WRITEFUNCTION, &write_data);  //指定处理接受数据的回调函数 
 23   //char p[1024]; 
 24   //curl_easy_setopt(_curl, CURLOPT_WRITEDATA, &p); 
 25   //curl_easy_setopt(_curl, CURLOPT_TIMEOUT, 60);    //设置设置传输时间 
 26   curl_easy_setopt(_curl, CURLOPT_CONNECTTIMEOUT, 3);  //设置连接等待时间 
 27   curl_easy_setopt(_curl, CURLOPT_ERRORBUFFER, &error_buf);  //output error info 
 28 
 29   //curl_easy_setopt(_curl, CURLOPT_VERBOSE, 1);  //pint debug info 
 30 
 31 } 
 32 
 33 hessian_proxy::~hessian_proxy(void) 
 34 { 
 35   if (_swap_OK)  //如果curl_easy_perform成功,释放http头的句柄 
 36     curl_slist_free_all(_http_headers); 
 37   curl_easy_cleanup(_curl);    
 38   curl_global_cleanup();    
 39 } 
 40 
 41 size_t hessian_proxy::write_data(void *buffer, size_t size, size_t nmemb, void *stream) 
 42 {        
 43   char httpsBuffer[1024];    
 44   memset(httpsBuffer, 0, sizeof(httpsBuffer)); 
 45   memcpy(httpsBuffer, buffer, nmemb);    
 46 
 47   _http_result.assign(httpsBuffer, nmemb+1); 
 48 
 49   return nmemb * size; 
 50 } 
 51 
 52 void hessian_proxy::set_share_handle() 
 53 { 
 54   if (!_share_handle) 
 55   {     
 56     _share_handle = curl_share_init();     
 57     curl_share_setopt(_share_handle, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);    //锁定DNS cache 
 58   }     
 59   curl_easy_setopt(_curl, CURLOPT_SHARE, _share_handle); 
 60   curl_easy_setopt(_curl, CURLOPT_DNS_CACHE_TIMEOUT, 60);  //超时时间内(60s) 每次curl_easy_perform执行时不会再启动解析DNS的线程了,提高效率 
 61 } 
 62 
 63 Object* hessian_proxy::call(const string& method, int argc, ... ) 
 64 { 
 65   Object *result = NULL; 
 66   try 
 67   { 
 68     hessian_output hout; 
 69     string mc = hout.start_call(method); 
 70 
 71     //添加参数 
 72     va_list ap; 
 73     va_start(ap, argc); 
 74     for (int i=0; i<argc; i++) 
 75     { 
 76       Object *param = va_arg(ap, Integer*);    
 77       hout.set_parameter(mc, param); 
 78     } 
 79     va_end(ap); 
 80     hout.complete_call(mc); 
 81 
 82     _num_calls++; 
 83 
 84     curl_easy_setopt(_curl, CURLOPT_URL, _url.c_str());        //设置url 
 85     curl_easy_setopt(_curl, CURLOPT_POSTFIELDS, mc.c_str());    //设置发送的数据 
 86     curl_easy_setopt(_curl, CURLOPT_POSTFIELDSIZE, mc.length());  //数据长度 
 87     memset(error_buf, 0, sizeof(error_buf)); 
 88 
 89     _res = curl_easy_perform(_curl);//执行 
 90     _swap_OK = false; 
 91     _is_exception = false; 
 92     if ( _res == CURLE_OK ) 
 93     { 
 94       _swap_OK = true; 
 95       auto_ptr<input_stream> sis(new string_input_stream(_http_result)); 
 96       hessian_input hes_in(sis); 
 97       hes_in.start_reply(); 
 98 
 99       result = hes_in.get_result(); 
100       hes_in.complete_reply(); 
101 
102       return result; 
103     } 
104      
105   } 
106   catch (io_exception* e) 
107   { 
108     _is_exception = true; 
109     if (e) 
110     { 
111       _str_exception.assign(e->what()); 
112       delete e; 
113       e = NULL; 
114     } 
115     if (result) 
116     { 
117       delete result; 
118       result = NULL; 
119     } 
120   } 
121   catch (io_exception e)    
122   { 
123     _is_exception = true; 
124     _str_exception.assign(e.what()); 
125     if (result) 
126     { 
127       result = NULL; 
128     } 
129   } 
130 
131   return NULL; 
132 } 
133 /* 
134 map<string, unsigned int>& hessian_proxy::call_size_map() 
135 { 
136   return m_call_size_map; 
137 } 
138 */ 
139 
140 string hessian_proxy::get_ip() const 
141 { 
142   char *tmp; 
143   if ( curl_easy_getinfo(_curl, CURLINFO_PRIMARY_IP, &tmp) == CURLE_OK ) 
144     return tmp; 
145   return NULL; 
146 } 
147 
148     
149 string hessian_proxy::get_url() const 
150 { 
151   char *tmp; 
152   if ( curl_easy_getinfo(_curl, CURLINFO_EFFECTIVE_URL, &tmp) == CURLE_OK ) 
153     return tmp; 
154   return NULL; 
155 } 
156 
157 long hessian_proxy::get_port() const 
158 { 
159   long tmp; 
160   if ( curl_easy_getinfo(_curl, CURLINFO_PRIMARY_PORT, &tmp) == CURLE_OK ) 
161     return tmp; 
162   return -1; 
163 } 
164 
165 double hessian_proxy::bytes_upload() 
166 { 
167   double tmp; 
168   if ( curl_easy_getinfo(_curl, CURLINFO_SIZE_UPLOAD, &tmp) == CURLE_OK ) 
169     return tmp; 
170   return -1; 
171 } 
172 
173 double hessian_proxy::bytes_download() 
174 { 
175   double tmp; 
176   if ( curl_easy_getinfo(_curl, CURLINFO_SIZE_DOWNLOAD, &tmp) == CURLE_OK ) 
177     return tmp; 
178   return -1; 
179 } 
180 
181 string hessian_proxy::get_error_info() 
182 { 
183   if (!_swap_OK) 
184     return error_buf; 
185   else if (_is_exception) 
186     return _str_exception; 
187   else 
188     return "Complete perform!"; 
189 } 
190 
191 long hessian_proxy::num_calls() 
192 { 
193   return _num_calls; 
194 }
下面我们就可以编写测试代码了:
新建一个main.cpp,加入:
 1 #include "hessian_proxy.h" 
 2 #include <iostream> 
 3 using namespace std; 
 4 
 5 int main() 
 6 { 
 7   hessian_proxy proxy("http://127.0.0.1:8080/hessian/HessianApi"); 
 8 
 9   Object* result = proxy.call("hello", 0); 
10   String* pStr = dynamic_cast<String *>(result); 
11   wcout << pStr->wvalue() << endl; 
12 
13   getchar(); 
14   return 0; 
15 }
这里之所以输出UNICODE字符串,是因为在我的机器上pStr->value()会使程序崩溃,如果你的也这样,可以找到String::value()的代码:
return to_string(_value);
改成:
return to_utf8_string(_value);
然后就可以:
cout << pStr->value() << endl;
 
posted @ 2013-04-09 23:11  晚来秋  阅读(820)  评论(0编辑  收藏  举报