GSOAP:使用模版封装Serivce线程
通过GSOAP自带的wsdl2h和soap2cpp可以生成基于C++语言的服务端代码Service和客户端代码Proxy,这样调用起来就很方便了。对于Service来说,只要将其放到一个线程中,等待客户端连接并相应请求就可以了;而对于客户端,直接调用Proxy对象的方法就可以向服务端发送请求了。
好用是好用,但如果Service很多的话,每个都写一次线程封装,这太可怕了,而一个线程带动全部Service由不现实,这时,C++模版的威力就体现出来了~看如下代码实例:
以上是对Service的封装,使用时,只要用如下语句即可:
下面是一个使用实例:
使用如上方法,只需编写Service相应的函数即可,大大减少编写重复代码的时间,爽了~
例子中使用的一个基类 ACEX_Synch_Task,是基于ACE封装的线程类,功能和其它线程类类似,svc()函数为线程处理部分函数。WebService使用的是一个通讯行业的接口规范,不复杂,就是Service多的要命~
GSOAP使用的感觉就是--厉害但不好用。。。。。可能是我对WebService规范和GSOAP不熟悉所致,反正用起来很不顺手,比如Service请求不能异步应答,对于通讯消息处理代码写多的我来说,这个很不习惯,当然也许是GSOAP支持,是我不会用。。。
GSOAP不好用,弄得我都想自己写个基于C++的WebService库来,但简单看了SOAP规范后,我放弃了。。。太复杂了,每个三五个月,是不可能实现的。。。
好用是好用,但如果Service很多的话,每个都写一次线程封装,这太可怕了,而一个线程带动全部Service由不现实,这时,C++模版的威力就体现出来了~看如下代码实例:
#ifndef __SOAPSERVICETASKTEMPLATE_H__
#define __SOAPSERVICETASKTEMPLATE_H__
#include < string >
#include < iostream >
#include " acex/ACEX.h "
#include " acex/Task.h "
#include " stdsoap2.h "
template < typename T >
class CSoapServiceObject : public T
{
public :
public :
CSoapServiceObject() {}
virtual ~ CSoapServiceObject() {}
int Init( const std:: string & strAddr);
void Shutdown() { _bStop = true ; }
public :
virtual int svc();
private :
bool _bStop;
std:: string _strHost;
unsigned short _usPort;
};
template < typename T >
int CSoapServiceObject < T > ::Init( const std:: string & strAddr)
{
std:: string ::size_type pos = strAddr.find( " : " );
if (pos != std:: string ::npos)
{
_strHost = strAddr.substr(pos + 1 );
_usPort = ACE_OS::atoi(_strHost.c_str());
_strHost = strAddr.substr( 0 , pos);
}
else
{
_usPort = ACE_OS::atoi(strAddr.c_str());
}
return 0 ;
}
template < typename T >
int CSoapServiceObject < T > ::svc()
{
if (_strHost.empty())
{
if ( ! soap_valid_socket( this -> bind(NULL, _usPort, 100 )))
return this -> error;
}
else
{
if ( ! soap_valid_socket( this -> bind(_strHost.c_str(), _usPort, 100 )))
return this -> error;
}
while ( ! _bStop)
{
if ( ! soap_valid_socket( this -> accept()))
return this -> error;
this -> serve();
soap_destroy( this );
soap_end( this );
}
return 0 ;
}
//////////////////////////////////////////////////////////////////////// //
template < typename T >
class CSoapServiceTask : public ACEX_Synch_Task
{
public :
CSoapServiceTask() {}
virtual ~ CSoapServiceTask() {}
int Init( const std:: string & strAddr);
void Shutdown();
protected :
virtual int svc();
private :
T _objService;
};
template < typename T >
int CSoapServiceTask < T > ::Init( const std:: string & strAddr)
{
return _objService.Init(strAddr);
}
template < typename T >
void CSoapServiceTask < T > ::Shutdown()
{
_objService.Shutdown();
}
template < typename T >
int CSoapServiceTask < T > ::svc()
{
return _objService.svc();
}
#endif
#define __SOAPSERVICETASKTEMPLATE_H__
#include < string >
#include < iostream >
#include " acex/ACEX.h "
#include " acex/Task.h "
#include " stdsoap2.h "
template < typename T >
class CSoapServiceObject : public T
{
public :
public :
CSoapServiceObject() {}
virtual ~ CSoapServiceObject() {}
int Init( const std:: string & strAddr);
void Shutdown() { _bStop = true ; }
public :
virtual int svc();
private :
bool _bStop;
std:: string _strHost;
unsigned short _usPort;
};
template < typename T >
int CSoapServiceObject < T > ::Init( const std:: string & strAddr)
{
std:: string ::size_type pos = strAddr.find( " : " );
if (pos != std:: string ::npos)
{
_strHost = strAddr.substr(pos + 1 );
_usPort = ACE_OS::atoi(_strHost.c_str());
_strHost = strAddr.substr( 0 , pos);
}
else
{
_usPort = ACE_OS::atoi(strAddr.c_str());
}
return 0 ;
}
template < typename T >
int CSoapServiceObject < T > ::svc()
{
if (_strHost.empty())
{
if ( ! soap_valid_socket( this -> bind(NULL, _usPort, 100 )))
return this -> error;
}
else
{
if ( ! soap_valid_socket( this -> bind(_strHost.c_str(), _usPort, 100 )))
return this -> error;
}
while ( ! _bStop)
{
if ( ! soap_valid_socket( this -> accept()))
return this -> error;
this -> serve();
soap_destroy( this );
soap_end( this );
}
return 0 ;
}
//////////////////////////////////////////////////////////////////////// //
template < typename T >
class CSoapServiceTask : public ACEX_Synch_Task
{
public :
CSoapServiceTask() {}
virtual ~ CSoapServiceTask() {}
int Init( const std:: string & strAddr);
void Shutdown();
protected :
virtual int svc();
private :
T _objService;
};
template < typename T >
int CSoapServiceTask < T > ::Init( const std:: string & strAddr)
{
return _objService.Init(strAddr);
}
template < typename T >
void CSoapServiceTask < T > ::Shutdown()
{
_objService.Shutdown();
}
template < typename T >
int CSoapServiceTask < T > ::svc()
{
return _objService.svc();
}
#endif
以上是对Service的封装,使用时,只要用如下语句即可:
if
(Service.Init(strAddr)
==
0
)
{
Service.activate();
}
{
Service.activate();
}
下面是一个使用实例:
#include
"
SoapServiceTaskTemplate.h
"
#include " soapSmsNotificationBindingService.h "
class CSoapNotifyServiceObject : public CSoapServiceObject < SmsNotificationBindingService >
{
public :
CSoapNotifyServiceObject();
virtual ~ CSoapNotifyServiceObject();
public :
virtual int notifySmsReception(isag5__notifySmsReception * isag5__notifySmsReception_, isag5__notifySmsReceptionResponse * isag5__notifySmsReceptionResponse_);
virtual int notifySmsDeliveryReceipt(isag5__notifySmsDeliveryReceipt * isag5__notifySmsDeliveryReceipt_, isag5__notifySmsDeliveryReceiptResponse * isag5__notifySmsDeliveryReceiptResponse_);
};
typedef CSoapServiceTask < CSoapNotifyServiceObject > TSoapNotifyServiceTask;
typedef ACE_Singleton < TSoapNotifyServiceTask, ACE_Recursive_Thread_Mutex > TSoapNotifyServiceTask_Singleton;
#define SoapNotifyServiceTask TSoapNotifyServiceTask_Singleton::instance()
#include " soapSmsNotificationBindingService.h "
class CSoapNotifyServiceObject : public CSoapServiceObject < SmsNotificationBindingService >
{
public :
CSoapNotifyServiceObject();
virtual ~ CSoapNotifyServiceObject();
public :
virtual int notifySmsReception(isag5__notifySmsReception * isag5__notifySmsReception_, isag5__notifySmsReceptionResponse * isag5__notifySmsReceptionResponse_);
virtual int notifySmsDeliveryReceipt(isag5__notifySmsDeliveryReceipt * isag5__notifySmsDeliveryReceipt_, isag5__notifySmsDeliveryReceiptResponse * isag5__notifySmsDeliveryReceiptResponse_);
};
typedef CSoapServiceTask < CSoapNotifyServiceObject > TSoapNotifyServiceTask;
typedef ACE_Singleton < TSoapNotifyServiceTask, ACE_Recursive_Thread_Mutex > TSoapNotifyServiceTask_Singleton;
#define SoapNotifyServiceTask TSoapNotifyServiceTask_Singleton::instance()
使用如上方法,只需编写Service相应的函数即可,大大减少编写重复代码的时间,爽了~
例子中使用的一个基类 ACEX_Synch_Task,是基于ACE封装的线程类,功能和其它线程类类似,svc()函数为线程处理部分函数。WebService使用的是一个通讯行业的接口规范,不复杂,就是Service多的要命~
GSOAP使用的感觉就是--厉害但不好用。。。。。可能是我对WebService规范和GSOAP不熟悉所致,反正用起来很不顺手,比如Service请求不能异步应答,对于通讯消息处理代码写多的我来说,这个很不习惯,当然也许是GSOAP支持,是我不会用。。。
GSOAP不好用,弄得我都想自己写个基于C++的WebService库来,但简单看了SOAP规范后,我放弃了。。。太复杂了,每个三五个月,是不可能实现的。。。