最近开发了一个基于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 "";
}
阅读(2173) | 评论(2) | 转发(0) |