1、开发环境请参考《搭建ACE-5.7.4+VS2008开发环境》一文
?
2、gSOAP库,下载地址:http://gsoap2.sourceforge.net/,本文使用的版本是:gsoap_2.7.15,gSOAP的编程可以参考doc目录下的soapdoc2.pdf,官方文档写的非常详细。
让我们开始gSOAP编码旅程:
1、创建gsoap_server.h:
- ??
- ??
- ??
- typedef?char?*?xsd__string;???
- int?xsd__int;???
- ??
- struct?ns2__makeCardNotifyReqBean??
- {??
- ????xsd__string?id_makecard_order;??
- ????xsd__int?card_type;??
- ????xsd__string?file_name;??
- ????xsd__string?start_card_serial;??
- ????xsd__string?end_card_serial;??
- ????xsd__int?card_count;??
- };??
- struct?ns2__makeCardNotifyRspBean??
- ????xsd__int?result;???
- ????xsd__string?error_desc;???
- //卡数据生成结果通知接口??
- int?ns2__makeCardNotify(struct?ns2__makeCardNotifyReqBean?req,?struct?ns2__makeCardNotifyRspBean?*rsp);??
注:头文件上面的注释用于配置服务访问地址,而非单纯的注释;详细配置说明可以参考官方文档
2、把%GSOAP_HOME%/gsoap/bin/win32目录配置到系统%Path%里,或者将目录下的soapcpp2.exe和wsdl2h.exe两个文件直接拷贝到gsoap_server.h所在目录;
3、编写批处理文件:
copy
echo?off??
- del?*.c?*.h?*.xml?*.nsmap?*.cpp??
- soapcpp2?-c?-S?gsoap_server.h??
- copy?soapC.c?../soapC.cpp??
- copy?soapServer.c?../soapServer.cpp??
- copy?soapH.h?../soapH.h??
- copy?soapStub.h?../soapStub.h??
- copy?ns2.nsmap?../gsoap_server.nsmap??
- echo?.??
- echo???
- echo?.??
- echo?生成的ns2.wsdl必须删除schemaLocation="http://schemas.xmlsoap.org/soap/encoding/"属性??
- pause??
4、编写业务实现代码:
copy
#include?<ctype.h>??
- #include?<string>??
- #include?<ace/OS.h>??
- #include?<ace/OS_NS_ctype.h>??
- #include?<ace/OS_NS_string.h>??
- #include?"Global_Define.h"??
- #include?"ffcs_logger.h"??
- #include?"stdsoap2.h"??
- #include?"soapH.h"??
- #include?"gsoap_server.nsmap"??
- extern?Logger?g_logger;??
- extern?GlobalValue?g_val;??
- /*-----------------------------------------------------------------------?
- *?name:?????卡数据生成结果通知接口?
- *?input:????soap??--?gSOAP运行时环境实例?
- *???????????req??--?SOAP请求参数?
- *?
- *?output:???rsp??--?SOAP应答参数?
- *?return:???SOAP_OK??--?成功?
- *???????????SOAP_ERR??--?失败:将导致客户端接口调用异常,一般不使用??
- *-----------------------------------------------------------------------*/??
- SOAP_FMAC5?int?SOAP_FMAC6?ns2__makeCardNotify(struct?soap*?soap,153); background-color:inherit; font-weight:bold">struct?ns2__makeCardNotifyRspBean?*rsp)??
- ????ACE_UINT64?ms_1,?ms_2;??
- ????ACE_OS::gettimeofday().msec(ms_1);??
- ????g_logger.debug("***?SOAP请求开始?***/n");??
- ????if?(req.id_makecard_order==NULL?||?req.file_name==NULL)??
- ????{??
- ????????g_logger.error("格式无效/n");??
- ????????rsp->result?=?RET_FORMATERROR;??
- ????????rsp->error_desc?=?"";??
- ????????return?SOAP_OK;??
- ????}??
- ????rsp->result?=?RET_SUCCESS;??
- ????rsp->error_desc?=?"成功";??
- ????ACE_OS::gettimeofday().msec(ms_2);??
- ????g_logger.debug("***?SOAP请求结束,耗时?(%ld)ms?***/n",?ms_2-ms_1);??
- return?SOAP_OK;??
- }??
5、编写WebService服务端处理代码:
copy
#include?<ace/OS.h>??
- /************************************************************************/??
- /*?全局变量?????????????????????????????????????????????????????????????*/??
- Logger?g_logger;??
- GlobalValue?g_val;??
- static?void?*?pthr_soap_server_process(void?*?arg);??
- void?*?pthr_soap_server_process_task(void?*?arg);??
- int?ACE_TMAIN(int?argc,?ACE_TCHAR*?argv[])??
- {??
- ????g_val.g_sys_run?=?1;??
- ??????
- ????g_logger.load_config(CONFIG_FILE);??
- ????g_logger.open_logger();??
- /*加载配置参数*/??
- if?(g_val.load_config(CONFIG_FILE)?==?-1)???
- ????????g_val.g_sys_run?=?0;??
- ????????g_logger.error("Load?config?file?[%s]?fail!/n",?CONFIG_FILE);??
- ????????ACE_OS::exit();??
- ????????return?0;??
- ????}??
- /*启动SOAP服务端,方式一*/??
- ?????
- ????if?(ACE_Thread_Manager::instance()->spawn_n(1,?
- ????????????????????????????????????????????????(ACE_THR_FUNC)pthr_soap_server_process,//Execute?task?one?
- ????????????????????????????????????????????????NULL,?//arguments?
- ????????????????????????????????????????????????THR_NEW_LWP?|?THR_DETACHED,?//New?Light?Weight?Process?
- ????????????????????????????????????????????????ACE_DEFAULT_THREAD_PRIORITY,0); background-color:inherit">????????????????????????????????????????????????FFCS_SOAP_SERVER_GRPID)==-1)?//Group?ID?
- ????????g_logger.error("Failure?to?spawn?/"pthr_soap_server_process/"?of?threads/n");?
- ????*/??
- /*启动SOAP服务端,方式二*/??
- ????if?(ACE_Thread_Manager::instance()->spawn_n(1,??
- ????????????????????????????????????????(ACE_THR_FUNC)pthr_soap_server_process_task,??
- ????????????????????????????????????????NULL,???
- ????????????????????????????????????????THR_NEW_LWP?|?THR_DETACHED,0); background-color:inherit">//New?Light?Weight?Process??
- ????????????????????????????????????????ACE_DEFAULT_THREAD_PRIORITY,??
- ????????????????????????????????????????FFCS_SOAP_SERVER_GRPID)==-1)???
- ????????g_logger.error("Failure?to?spawn?/"pthr_soap_server_process_task/"?of?threads/n");??
- while(g_val.g_sys_run?==?1)???
- ????{??
- ????????ACE_OS::sleep(1);??
- }??
- /*采用线程池的方式处理SOAP?Client请求*/??
- void?*?arg)??
- ????char?cHost[]?=?"localhost";???
- ????int?iPort?=?9908;???
- struct?soap?soap;??
- ????SOAP_SOCKET?m,?s;??
- int?i;??
- struct?timespec?rqt;??
- struct?soap?*soap_thr[MAX_THR];???
- ????ACE_thread_t?tid[MAX_THR];???
- //初始化连接池运行时环境实例??
- for?(i?=?0;?i?<?MAX_THR;?i++)???
- ????????soap_thr[i]?=?NULL;??
- ????????tid[i]?=?0;??
- /*初始化服务*/??
- ????soap_init(&soap);??
- do???
- ????????m?=?soap_bind(&soap,?cHost,?iPort,?BACKLOG);??
- if?(!soap_valid_socket(m))???
- ????????{??
- ????????????g_logger.error("Socket?bind?fail?(%d);System?retry?after?10?seconds/n");??
- ????????????ACE_OS::sleep(10);??
- ????????????continue;??
- ????????}???
- else???
- ????????????g_logger.debug("Socket?%d?connection?successful?%s?on?port?%d/n",?m,?iPort);??
- ????????????break;??
- ????????}??
- ????}?while?(g_val.g_sys_run?==?1);??
- /*处理请求*/??
- while?(g_val.g_sys_run?==?1)??
- for?(i?=?0;?i?<?MAX_THR;?i++)???
- ????????????s?=?soap_accept(&soap);??
- if?(!soap_valid_socket(s))???
- ????????????{??
- ????????????????if?(soap.errnum)???
- ????????????????{??
- ????????????????????g_logger.error("SOAP异常:%d/n",?soap.errnum);??
- ????????????????????continue;???
- ????????????????}???
- ???????????????? ????????????????{??
- ????????????????????g_logger.error("Server?timed?out/n");??
- ???????????????????? ????????????????}??
- ????????????}??
- ????????????g_logger.debug("Thread?%d?accepts?socket?%d?connection?from?IP?%d.%d.%d.%d/n",?i,?s,?(soap.ip?>>?24)&0xFF,?(soap.ip?>>?16)&0xFF,?(soap.ip?>>?8)&0xFF,?soap.ip&0xFF);??
- if?(!soap_thr[i])???
- ????????????????soap_thr[i]?=?soap_copy(&soap);??
- if?(!soap_thr[i])???
- ????????????????????g_logger.error("系统异常/n");??
- ????????????}???
- else???
- ????????????{???
- ????????????????ACE_Thread_Manager::instance()->join(tid[i]);??
- ????????????????g_logger.debug("OLD?Thread?%d?completed/n",?i);??
- ????????????????soap_destroy(soap_thr[i]);??
- ????????????????soap_end(soap_thr[i]);??
- ????????????}??
- ????????????soap_thr[i]->socket?=?s;??
- ??????????????
- ????????????soap_set_imode(soap_thr[i],?SOAP_C_UTFSTRING);??
- ??????????????
- ????????????tid[i]?=?ACE_Thread_Manager::instance()->spawn_n(1,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px"> ????????????????????????????????????????????????????????????(ACE_THR_FUNC)soap_serve,248); line-height:18px"> ????????????????????????????????????????????????????????????(void*)soap_thr[i],?
- ??????????????
- if?(tid[i]?==?-1)?g_logger.error("Failure?to?spawn?/"soap_serve/"?of?threads/n");??
- ????????}??
- ????????rqt.tv_sec?=?0;??
- ????????rqt.tv_nsec?=?10000000;??
- ????????ACE_OS::nanosleep(&rqt);??
- //释放资源??
- if?(soap_thr[i])???
- ????????{??
- ????????????soap_free(soap_thr[i]);???
- ????soap_done(&soap);???
- return?0;??
- }??
- /*采用线程池+消息队列的方式处理SOAP?Client请求*/??
- struct?soap?*pSoap;??
- ????SOAP_SOCKET?m,?s;??
- ????TaskSoapClient?task_soap_client;??
- /*创建消息处理ACE_Task*/??
- ????task_soap_client.set_active(true);??
- if?(task_soap_client.activate(THR_NEW_LWP?|?THR_JOINABLE,?TASK_SOAP_CLIENT_POOL_SIZE)?==?-1)??
- ????????g_logger.error("TaskSoapClient?activate?failed/n");??
- ????????s?=?soap_accept(&soap);??
- ????????????????g_logger.error("SOAP异常:%d/n",248); line-height:18px"> ????????????{??
- ????????????????g_logger.error("Server?timed?out/n");??
- ????????g_logger.debug("Accepts?socket?%d?connection?from?IP?%d.%d.%d.%d/n",248); line-height:18px"> ????????pSoap?=?soap_copy(&soap);??
- if?(!pSoap)???
- ????????????g_logger.error("系统异常/n");??
- continue;??
- ????????pSoap->socket?=?s;??
- ??????????
- ????????soap_set_imode(pSoap,?SOAP_C_UTFSTRING);??
- ??????????
- ????????task_soap_client.process_soap_client_requet((void?*)pSoap);??
- ????????rqt.tv_sec?=?0;??
- ????????rqt.tv_nsec?=?50000000;??
- ????????ACE_OS::nanosleep(&rqt);??
- ????task_soap_client.set_active(false);??
- ????task_soap_client.msg_queue()->close();??
- ????task_soap_client.wait();??
- }??
6、如果采用线程池+消息队列的方式处理SOAP Client请求,需要引入ACE_Task,并采用ACE_Message_Block实现对了操作:
copy
/********************************************************************************************?
- *?huangjf?2009年12月?于福州?
- ********************************************************************************************/??
- #include?"ffcs_common.h"??
- #include?"stdsoap2.h"??
- #include?"soapH.h"??
- /********************************************************************************************?
- *?WebService?Client?Requet?处理类?
- ********************************************************************************************/??
- class?TaskSoapClient:?public?ACE_Task<ACE_MT_SYNCH>??
- public:??
- ????TaskSoapClient()?:?active_(false)??
- this->active_?=?false;??
- this->msg_queue()->high_water_mark(SOAP_HIGHT_MARK);??
- ????????ACE_DEBUG((LM_DEBUG,?ACE_TEXT("(%P|%t)?TaskSoapClient?start/n")));??
- virtual?~TaskSoapClient()??
- false;??
- this->msg_queue()->close();??
- ????????ACE_DEBUG((LM_DEBUG,?ACE_TEXT("(%P|%t)?TaskSoapClient?stop/n")));??
- virtual?int?svc(void);??
- bool?get_active();??
- void?set_active(bool?b);??
- int?process_soap_client_requet(void?*soap);??
- private:??
- bool?active_;??
- void?process_soap(ACE_Message_Block?*mb?=?NULL);??
- //处理接收队列??
- int?TaskSoapClient::svc(void)??
- ????g_logger.debug("TaskSoapClient::svc()?start/n");??
- while?(this->active_==true)??
- ????????ACE_Message_Block?*mb?=?NULL;??
- if?(this->getq(mb)?==?-1)??
- /*g_logger.error("取接收队列数据失败/n");*/??
- ????????process_soap(mb);??
- ????g_logger.debug("TaskSoapClient::svc()?stop/n");??
- void?TaskSoapClient::process_soap(ACE_Message_Block?*mb)??
- char?*?data?=?mb->rd_ptr();??
- size_t?data_size?=?mb->length();??
- /*g_logger.dump(data,?data_size,?1);*/??
- /****************************************************************?
- ????*?TODO?处理接收到的SOAP?Client?Request,数据的起始地址为data,长度为data_size?
- ????*****************************************************************/??
- struct?soap?*?pSoap?=?NULL;???
- try??
- ????????ACE_OS::memcpy(&pSoap,?data,?MIN(data_size,?sizeof(void?*)));??
- catch?(...)??
- ????????g_logger.error("struct?soap?*?转换异常/n");??
- return;??
- if?(pSoap)??
- if?(!soap_valid_socket(pSoap->socket))???
- if?(pSoap->errnum)???
- ????????????}???
- else???
- ????????????????g_logger.error("SOAP异常:??/n");??
- ????????????soap_free(pSoap);??
- return;??
- ????????soap_serve(pSoap);?????
- ????????soap_destroy(pSoap);???
- ????????soap_end(pSoap);???????
- ????????soap_free(pSoap);??????
- //数据处理结束必需释放内存??
- ????mb->release();??
- /**********************************************************************************************************************************/??
- void?TaskSoapClient::set_active(bool?b)??
- this->active_?=?b;??
- bool?TaskSoapClient::get_active()??
- return?this->active_;??
- int?TaskSoapClient::process_soap_client_requet(void?*soap)??
- int?msg_len?=?void?*);??
- ????ACE_Message_Block?*mb?=?NULL;??
- ????ACE_NEW_RETURN(mb,?ACE_Message_Block(msg_len+1),?-1);??
- ????ACE_OS::memcpy(mb->wr_ptr(),?&soap,?msg_len);??
- ????mb->wr_ptr(msg_len);??
- this->putq(mb)?==?-1)??
- ????????g_logger.error("SOAP?Client?Requet?enqueue?to?TaskSoapClient?failed/n");??
- ????????mb->release();??
- return?-1;??
- return?1;??
- 7、编译的时候不要忘记将%GSOAP_HOME%/gsoap/目录下的stdsoap2.cpp和stdsoap2.h引入工程;
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|