最近開發了一個基于ACE實現的C++ Service框架,每一個服務實現為一個插件,
客戶端通過遠程調用接口即可訪問服務對象提供的服務,客戶端接口的包裝如下所示:
#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);
}
};
一個網絡應用一般包括兩部分,位于服務端的“服務對象”和位于客戶端的“調用代理”,上面這個類屬于客戶端代理對象。
兩端之間遵從的協議就是請求“LoginRequest”和響應“LoginResult ”。
@欲三更
非常對,CPPX_LoginService就是用戶協議的封裝,屬于表示層范疇,其中的參數CPPX_SessionIO &peer屬于會話層對象,
連接建立以后會返回一個peer對象,調用什么服務就創建一個響應的服務對象,如調用CPPX_LoginService:
void fuClientMainWindow::connect_open( CPPX_SessionIO &peer )
{
// 保存會話對象,以供主動發送數據使用
m_peer = peer;
// 調用登錄服務
CPPX_LoginService login_svc(peer);
bool result = login_svc.apiUserLogin("funix","letmein");
}
CPPX_SessionIO 類是會話對象CPPX_Session的weak_ptr引用,weak_ptr是boost中定義的觀察者智能指針,利用boost::weak_ptr和boost::shared_ptr可以實現帶有引用計數的對象實例引用。
#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;
/*
* 必須手動定義析構函數,因為編譯器生成的隱式析構函數時,
* pimpl_t類型還是不完整的,所以無法調用它的析構函數。
*/
public:
CPPX_SessionIO(void);
~CPPX_SessionIO(void);
public:
// 顯式構造函數:創建CPPX_Session的weak_ptr引用
explicit CPPX_SessionIO(CPPX_Session * Session, long SessionID);
/*
* 當使用scoped_ptr作為類的成員時,需要手動定義這個類的copy constructor和copy assignment operator,
* 因為scoped_ptr無法復制,因此聚集scoped_ptr的類也就不能進行復制。
*/
public:
// 拷貝構造函數:復制CPPX_Session的weak_ptr引用
CPPX_SessionIO(const CPPX_SessionIO & copy);
// 賦值操作符:監聽器獲取會話引用,用戶建立連接時保存引用對象
void operator = (const CPPX_SessionIO ©);
public:
// 用于監聽器查找會話引用,關閉連接時清除引用對象
bool operator == (const CPPX_SessionIO ©) const;
public:
// 狀態操作
long getid(void);
bool valid(void);
void close(void);
// 發送異步消息
void send(const char *buffer,int length);
void send(const string &message);
void send(const char *message);
// 等待會話返回該請求的響應消息
string expect(string service,string request);
// 同步遠程調用
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 : 異步請求響應等待
return "";
}
posted on 2009-07-22 13:16
風雷九州 閱讀(2942)
評論(5) 編輯 收藏 引用