最近開發(fā)了一個(gè)基于ACE實(shí)現(xiàn)的C++ Service框架,每一個(gè)服務(wù)實(shí)現(xiàn)為一個(gè)插件,
客戶端通過(guò)遠(yuǎn)程調(diào)用接口即可訪問(wèn)服務(wù)對(duì)象提供的服務(wù),客戶端接口的包裝如下所示:
#pragma once
#include "CPPX_SessionIO.h"
class CPPX_LoginService
{
class LoginRequest : public CPPX_Packet<LoginRequest>
{
public:
LoginRequest(void) : CPPX_Packet<LoginRequest>(*this) {}
string UserName;
string PassWord;
template<class Archive>
void serialize(Archive & ar, const unsigned int version){
ar & UserName;
ar & PassWord;
}
};
class LoginResult : public CPPX_Packet<LoginResult>
{
public:
LoginResult(void) : CPPX_Packet<LoginResult>(*this){}
bool success;
template<class Archive>
void serialize(Archive & ar, const unsigned int version){
ar & success;
}
};
CPPX_SessionIO & m_peer;
public:
CPPX_LoginService(CPPX_SessionIO &peer) : m_peer(peer) {}
bool apiUserLogin(string UserName,string PassWord){
LoginRequest login_request;
login_request.ServiceName = "authsvc";
login_request.RequestType = "apiUserLogin";
login_request.UserName = UserName;
login_request.PassWord = PassWord;
LoginResult login_result;
uint reuslt = m_peer.call(login_request,login_result);
return (reuslt==0)&&(login_result.success);
}
};
一個(gè)網(wǎng)絡(luò)應(yīng)用一般包括兩部分,位于服務(wù)端的“服務(wù)對(duì)象”和位于客戶端的“調(diào)用代理”,上面這個(gè)類屬于客戶端代理對(duì)象。
兩端之間遵從的協(xié)議就是請(qǐng)求“LoginRequest”和響應(yīng)“LoginResult ”。
@欲三更
非常對(duì),CPPX_LoginService就是用戶協(xié)議的封裝,屬于表示層范疇,其中的參數(shù)CPPX_SessionIO &peer屬于會(huì)話層對(duì)象,
連接建立以后會(huì)返回一個(gè)peer對(duì)象,調(diào)用什么服務(wù)就創(chuàng)建一個(gè)響應(yīng)的服務(wù)對(duì)象,如調(diào)用CPPX_LoginService:
void fuClientMainWindow::connect_open( CPPX_SessionIO &peer )
{
// 保存會(huì)話對(duì)象,以供主動(dòng)發(fā)送數(shù)據(jù)使用
m_peer = peer;
// 調(diào)用登錄服務(wù)
CPPX_LoginService login_svc(peer);
bool result = login_svc.apiUserLogin("funix","letmein");
}
CPPX_SessionIO 類是會(huì)話對(duì)象CPPX_Session的weak_ptr引用,weak_ptr是boost中定義的觀察者智能指針,利用boost::weak_ptr和boost::shared_ptr可以實(shí)現(xiàn)帶有引用計(jì)數(shù)的對(duì)象實(shí)例引用。
#pragma once
#include "dllmain.h"
#include "CPPX_Packet.h"
#include <boost/scoped_ptr.hpp>
class CPPX_Session;
class CPPX_SVC_API CPPX_SessionIO
{
class pimpl_t;
boost::scoped_ptr<pimpl_t> pimpl_;
long m_session_id;
/*
* 必須手動(dòng)定義析構(gòu)函數(shù),因?yàn)榫幾g器生成的隱式析構(gòu)函數(shù)時(shí),
* pimpl_t類型還是不完整的,所以無(wú)法調(diào)用它的析構(gòu)函數(shù)。
*/
public:
CPPX_SessionIO(void);
~CPPX_SessionIO(void);
public:
// 顯式構(gòu)造函數(shù):創(chuàng)建CPPX_Session的weak_ptr引用
explicit CPPX_SessionIO(CPPX_Session * Session, long SessionID);
/*
* 當(dāng)使用scoped_ptr作為類的成員時(shí),需要手動(dòng)定義這個(gè)類的copy constructor和copy assignment operator,
* 因?yàn)閟coped_ptr無(wú)法復(fù)制,因此聚集scoped_ptr的類也就不能進(jìn)行復(fù)制。
*/
public:
// 拷貝構(gòu)造函數(shù):復(fù)制CPPX_Session的weak_ptr引用
CPPX_SessionIO(const CPPX_SessionIO & copy);
// 賦值操作符:監(jiān)聽器獲取會(huì)話引用,用戶建立連接時(shí)保存引用對(duì)象
void operator = (const CPPX_SessionIO ©);
public:
// 用于監(jiān)聽器查找會(huì)話引用,關(guān)閉連接時(shí)清除引用對(duì)象
bool operator == (const CPPX_SessionIO ©) const;
public:
// 狀態(tài)操作
long getid(void);
bool valid(void);
void close(void);
// 發(fā)送異步消息
void send(const char *buffer,int length);
void send(const string &message);
void send(const char *message);
// 等待會(huì)話返回該請(qǐng)求的響應(yīng)消息
string expect(string service,string request);
// 同步遠(yuǎn)程調(diào)用
template<class PacketT,class ResultT>
uint call(const CPPX_Packet<PacketT> & request, CPPX_Packet<ResultT> & result){
send(request.pack());
string response = expect(request.ServiceName,request.RequestType);
result.unpack(response);
return 0;
}
};
#include "CPPX_SessionIO.h"
#include "CPPX_SessionIO_Pimpl.h"
#include <boost/shared_ptr.hpp>
static CPPX_Session * null_session = 0;
CPPX_SessionIO::CPPX_SessionIO( void )
: pimpl_(new pimpl_t(null_session)),
m_session_id(0)
{
}
CPPX_SessionIO::~CPPX_SessionIO( void )
{
}
CPPX_SessionIO::CPPX_SessionIO( CPPX_Session * Session, long SessionID )
: pimpl_(new pimpl_t(Session)),
m_session_id(SessionID)
{
}
CPPX_SessionIO::CPPX_SessionIO( const CPPX_SessionIO & copy )
: pimpl_(new pimpl_t(null_session))
{
*this = copy;
}
void CPPX_SessionIO::operator=( const CPPX_SessionIO © )
{
pimpl_->session_ptr = copy.pimpl_->session_ptr;
}
bool CPPX_SessionIO::operator==( const CPPX_SessionIO © ) const
{
return m_session_id == copy.m_session_id;
}
long CPPX_SessionIO::getid( void )
{
return m_session_id;
}
bool CPPX_SessionIO::valid( void )
{
if( CPPX_Session::shared_ptr safePtr = pimpl_->session_ptr.lock() )
return true;
return false;
}
void CPPX_SessionIO::close( void )
{
if( CPPX_Session::shared_ptr safePtr = pimpl_->session_ptr.lock() )
safePtr->close();
}
void CPPX_SessionIO::send( const char *buffer,int length )
{
if( CPPX_Session::shared_ptr safePtr = pimpl_->session_ptr.lock() )
safePtr->send(buffer,length);
}
void CPPX_SessionIO::send( const char *message )
{
send(message,strlen(message)+1);
}
void CPPX_SessionIO::send( const string &message )
{
send(message.c_str(),message.length());
}
string CPPX_SessionIO::expect( string service,string request )
{
// TODO : 異步請(qǐng)求響應(yīng)等待
return "";
}
posted on 2009-07-22 13:16
風(fēng)雷九州 閱讀(2941)
評(píng)論(5) 編輯 收藏 引用