GSOAP:使用模版封装Serivce线程

GSOAP:使用模版封装Serivce线程

通过GSOAP自带的wsdl2h和soap2cpp可以生成基于C++语言的服务端代码Service和客户端代码Proxy,这样调用起来就很方便了。对于Service来说,只要将其放到一个线程中,等待客户端连接并相应请求就可以了;而对于客户端,直接调用Proxy对象的方法就可以向服务端发送请求了。
    好用是好用,但如果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


    以上是对Service的封装,使用时,只要用如下语句即可:
if (Service.Init(strAddr)  ==   0 )
{
  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()

    使用如上方法,只需编写Service相应的函数即可,大大减少编写重复代码的时间,爽了~
    例子中使用的一个基类 ACEX_Synch_Task,是基于ACE封装的线程类,功能和其它线程类类似,svc()函数为线程处理部分函数。WebService使用的是一个通讯行业的接口规范,不复杂,就是Service多的要命~

    GSOAP使用的感觉就是--厉害但不好用。。。。。可能是我对WebService规范和GSOAP不熟悉所致,反正用起来很不顺手,比如Service请求不能异步应答,对于通讯消息处理代码写多的我来说,这个很不习惯,当然也许是GSOAP支持,是我不会用。。。

    GSOAP不好用,弄得我都想自己写个基于C++的WebService库来,但简单看了SOAP规范后,我放弃了。。。太复杂了,每个三五个月,是不可能实现的。。。

你可能感兴趣的:(GSOAP:使用模版封装Serivce线程)