随笔 - 6  文章 - 11  trackbacks - 0
<2009年7月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

常用链接

留言簿(1)

随笔档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜

最近开发了一个基于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 &copy);

public:
    
// 用于监听器查找会话引用,关闭连接时清除引用对象
    bool operator == (const CPPX_SessionIO &copy) 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 &copy )
{
    pimpl_
->session_ptr = copy.pimpl_->session_ptr;
}

bool CPPX_SessionIO::operator==const CPPX_SessionIO &copy ) 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 风雷九州 阅读(2912) 评论(5)  编辑 收藏 引用

FeedBack:
# re: C++实现远程服务对象调用 2009-07-22 13:50 vczh
那还是要自己写的啊。  回复  更多评论
  
# re: C++实现远程服务对象调用 2009-07-23 11:29 funix
@vczh

按照CORBA的结构,这部分因该算是客户端的“桩”,还有服务端的“框架”,这些都应该是系统自动生成的代码,只要编写一个类似的“接口定义”文件即可,目前我也在研究中,我并不是想再造一个CORBA,只是为了学习服务器开发的这种模式。  回复  更多评论
  
# re: C++实现远程服务对象调用 2009-07-25 12:09 nctt
糟糕的设计,服务特性不一,很难有效地管理,分布应用更麻烦。
建议每个处理单元只处理单独几个特性近似的服务。每个session分配一个轻量级进程,基于消息通信。处理单元之间的通信以及与网络的通信可通过高性能的FPGA实现,FPGA同时负责打包解包,任务分发。  回复  更多评论
  
# re: C++实现远程服务对象调用[未登录] 2009-07-30 20:22 欲三更
这个看起来是客户端用的dll的一部分吧?

从代码没看出来“远程对象调用”这个主题啊,感觉就是把client和server之间的通信协议封装起来了,client看到的是一个接口,或者说proxy类,调用它的方法,它就按照一定的通信规约把命令传给server,再接收server传过来的结果,是这个意思吧?  回复  更多评论
  
# re: C++实现远程服务对象调用 2009-08-01 21:53 风雷九州
@nctt

不知所云  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理