源码下载:http://download.csdn.net/detail/javacmm2012/5575805
1. CORBA准备:http://blog.csdn.net/javacmm2012/article/details/9005429
2 . 编写IDL文件,作为静态库供客户端和服务端调用,代码如下:
#ifndef IUserCfgServant_IDL_
#define IUserCfgServant_IDL_
struct sDataTime
{
/*日期时间类型*/
short iYear;
short iMonth;
short iDay;
short iHour;
short iMinute;
short iSeconds;
};
struct sItem
{
/*用户Item数据结构*/
short iItemId; /*对每一个用户来说的唯一Id*/
sDataTime sStartTime;
sDataTime sEndTime;
string strLabel;
};
typedef sequence<sItem> seqItem;
struct sUser
{
short iUserId; /*用户唯一Id*/
string strUserName; /*用户名*/
string strPassword; /*密码*/
seqItem seqItems; /*用户的item集合*/
};
interface IUserCfgServant
{
//返回字符串
string echoString(in string mesg);
//加法运算
long add(in long p1,in long p2);
/// 用户注册
boolean addUser( in string username, in string password );
/// 查询用户是否存在,可用作客户端登陆与查询用户信息
boolean queryUser( in string username, in string password, out sUser user );
/// 更新用户信息,可用作删除Item,或者增加Item来用
boolean updateUserInfo( in sUser user );
};
#endif ///<IUserCfgServant_IDL_
然后使用自定义工具tao_idl编译该文件,在VS2012配置如下:
注意:如果没有tao_idl.exe, 则转向CORBA工程编译工程名为TAO_IDL_EXE的工程,会在\ACE_wrappers\bin下生成tao_idl.exe
此后,将生成的*S.h*C.h*S.cpp*C.cpp添加到IDL工程,然后编译生成静态库IDL.lib
3. 编写服务端工程
新建个新工程,命名为Server, 新建个类CIUserCfgServant_i用于实现接口文件IDL中定义的所有方法,代码如下:
#ifndef ECHO_I_H_
#define ECHO_I_H_
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <vector>
#include "../IDL/IUserCfgServantS.h"
//命名服务类
#include "orbsvcs/CosNamingC.h"
class CIUserCfgServant_i:public POA_IUserCfgServant,public PortableServer::RefCountServantBase
{
public:
CIUserCfgServant_i();
virtual ~CIUserCfgServant_i();
virtual char* echoString(const char* mesg);
//实现加法运算
virtual CORBA::Long add(::CORBA::Long p1, ::CORBA::Long p2);
//增加用户
virtual CORBA::Boolean addUser (
const char * username,
const char * password);
//查询用户
virtual CORBA::Boolean queryUser (
const char * username,
const char * password,
sUser_out user);
//更新用户信息
virtual CORBA::Boolean updateUserInfo (
const sUser & user);
private:
bool writeToFile(); //将对象信息存入文件
bool readFromFile(); //读取用户信息
private:
std::vector<sUser> m_vecUser; //所有用户信息
fstream m_filedata; //文件读取用
};
#endif ///<ECHO_I_H_
编写注册命名服务(IUserCfgServant)的代码,如下:
#include <iostream>
#include "IUserCfgServant_i.h"
using namespace std;
int main(int argc, char * argv[])
{
try {
//初始化CORBA
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
CORBA::Object_var poa_object =
orb->resolve_initial_references ("RootPOA");
PortableServer::POA_var poa =
PortableServer::POA::_narrow (poa_object.in ());
PortableServer::POAManager_var poa_manager =
poa->the_POAManager ();
poa_manager->activate ();
CORBA::Object_var naming_context_object = orb->resolve_initial_references("NameService");
CosNaming::NamingContext_var naming_context =
CosNaming::NamingContext::_narrow (naming_context_object.in ());
CosNaming::Name name (1);
name.length (1);
name[0].id = CORBA::string_dup ("IUserCfgServant");
CIUserCfgServant_i* myecho = new CIUserCfgServant_i();
IUserCfgServant_var echo_var = myecho->_this();
try
{
naming_context->bind(name, echo_var.in ());
}
catch(CosNaming::NamingContext::AlreadyBound& ex)
{
cerr<< ex._info() << endl;
naming_context->rebind(name, echo_var.in ());
}
cout<<"server start success..."<<endl;
orb->run();
poa->destroy(1,1);
orb->destroy();
}
catch(CORBA::SystemException& e) {
cerr << e._info() <<endl;
cerr << "Caught CORBA::SystemException." << endl;
}
catch(CORBA::Exception& e) {
cout<< e._info() << endl;
cerr << "Caught CORBA::Exception." << endl;
}
catch(...) {
cerr << "Caught unknown exception." << endl;
}
return 0;
}
工程配置,包含CORBA所需要的库,加上指定的静态接口库IDL.lib,配置如图:
4.编写客户端工程:
新建个工程Client, 代码如下:
#include <iostream>
#include <iomanip>
#include <sstream>
// TAO头文件
#include "tao/AnyTypeCode/AnyTypeCode_methods.h"
#include "tao/AnyTypeCode/Any.h"
#include "tao/ORB.h"
#include "tao/SystemException.h"
#include "tao/Basic_Types.h"
#include "tao/ORB_Constants.h"
#include "tao/Object.h"
#include "tao/String_Manager_T.h"
#include "tao/Objref_VarOut_T.h"
#include "tao/VarOut_T.h"
#include "tao/Versioned_Namespace.h"
#include "tao/PortableServer/PortableServer.h"
#include "tao/PortableServer/Servant_Base.h"
#include "tao/orbsvcs/Naming_Service/Naming_Service.h"
// TAO头文件
#include "../IDL/IUserCfgServantC.h"
IUserCfgServant_var _varEchoMgr;
CORBA::ORB_var _varORB;
sUser _userInfo;
bool _bIsLogin = false;
void printHelp(); //打印帮助菜单
using namespace std;
int main(int argc, char* argv[]) {
try {
// initialize orb
_varORB = CORBA::ORB_init(argc, argv);
// Obtain reference from servant IOR
CORBA::Object_var naming_context_object = _varORB->resolve_initial_references( "NameService" );
if ( CORBA::is_nil(naming_context_object.in()) )
return false;
CosNaming::NamingContext_var naming_context = CosNaming::NamingContext::_narrow( naming_context_object.in() );
/*CosNaming::Name name(1);
name.length(1);
name[0].id = CORBA::string_dup( "IControlUnitDeviceServant" );*/
CosNaming::Name name(1);
name.length(1);
name[0].id = CORBA::string_dup( "IUserCfgServant" );
CORBA::Object_var project_object = naming_context->resolve( name );
if ( CORBA::is_nil(project_object.in()) )
return false;
// Now downcast the object reference to the appropriate type
_varEchoMgr = IUserCfgServant::_narrow( project_object.in() );
while( true )
{
// std::string temp;
// cout<<"input a string:";
// cin>>temp;
// temp = _varEchoMgr->echoString( temp.c_str() );
// cout<<"from server:"<<temp<<endl;
// int a,b;
// cout<<"input two integer:";
// cin>>a>>b;
// int result = _varEchoMgr->add(a,b);
// cout<<a<<"+"<<b<<"="<<result<<endl;
string command;
cin>>command;
if( "help" == command )
{
printHelp();
}
else if( "register" == command )
{
string username;
string password;
cin>>username; //用户名
cin>>password; //密码
if( !_varEchoMgr->addUser(username.c_str(),password.c_str()))
{
cerr<<"username has been registered"<<endl;
}else
{
cout<<"register success"<<endl;
}
}
else if( "login" == command )
{
string username;
string password;
cin>>username; //用户名
cin>>password; //密码
sUser_var uservar;
if( !_varEchoMgr->queryUser(username.c_str(),password.c_str(),uservar) )
{
cerr<<"invalid login"<<endl;
}else
{
system("cls");
cout<<"welcome "<<username<<endl;
_userInfo = *uservar;
_bIsLogin = true;
}
}
else if( "add" == command )
{
if( _bIsLogin )
{
sItem item;
//先读取开始时间
char ch;
cin>>item.sStartTime.iYear;
cin>>ch; //跳过/
cin>>item.sStartTime.iMonth;
cin>>ch; //跳过/
cin>>item.sStartTime.iDay;
cin>>item.sStartTime.iHour;
cin>>ch; //跳过:
cin>>item.sStartTime.iMinute;
cin>>ch; //跳过:
cin>>item.sStartTime.iSeconds;
//再读结束时间
cin>>item.sEndTime.iYear;
cin>>ch; //跳过/
cin>>item.sEndTime.iMonth;
cin>>ch; //跳过/
cin>>item.sEndTime.iDay;
cin>>item.sEndTime.iHour;
cin>>ch; //跳过:
cin>>item.sEndTime.iMinute;
cin>>ch; //跳过:
cin>>item.sEndTime.iSeconds;
//再读Label
string strTmp;
cin>>strTmp;
item.strLabel = CORBA::string_dup( strTmp.c_str() );
int iLength = _userInfo.seqItems.length();
if( 0==iLength )
{
item.iItemId = 1;
}else
{
item.iItemId = _userInfo.seqItems[iLength-1].iItemId+1;
}
_userInfo.seqItems.length(iLength+1);
_userInfo.seqItems[iLength] = item;
if( _varEchoMgr->updateUserInfo(_userInfo) )
{
cout<<"add success"<<endl;
}else
{
cout<<"add failed"<<endl;
}
}else
{
cerr<<"please login first"<<endl;
}
}
else if( "querya" == command )
{
if( _bIsLogin )
{
//查询所有的Item
int iLength = _userInfo.seqItems.length();
stringstream stream;
for( int j = 0 ;j<iLength; j++)
{
//先输出Id;
cout<<setw(5)<<setiosflags(ios::left)<<"itemId:"<<_userInfo.seqItems[j].iItemId<<" ";
//输出开始时间
stream.str("");
stream<<
_userInfo.seqItems[j].sStartTime.iYear<<"/"<<
_userInfo.seqItems[j].sStartTime.iMonth<<"/"<<
_userInfo.seqItems[j].sStartTime.iDay<<" "<<
_userInfo.seqItems[j].sStartTime.iHour<<":"<<
_userInfo.seqItems[j].sStartTime.iMinute<<":"<<
_userInfo.seqItems[j].sStartTime.iSeconds;
cout<<setw(22)<<setiosflags(ios::left)<<stream.str();
//输出结束时间
stream.str("");
stream<<
_userInfo.seqItems[j].sStartTime.iYear<<"/"<<
_userInfo.seqItems[j].sStartTime.iMonth<<"/"<<
_userInfo.seqItems[j].sStartTime.iDay<<" "<<
_userInfo.seqItems[j].sStartTime.iHour<<":"<<
_userInfo.seqItems[j].sStartTime.iMinute<<":"<<
_userInfo.seqItems[j].sStartTime.iSeconds;
cout<<setw(22)<<setiosflags(ios::left)<<stream.str();
//输出label
cout<<setw(20)<<setiosflags(ios::left)<<_userInfo.seqItems[j].strLabel.in()<<endl;
}
}else
{
cerr<<"please login first"<<endl;
}
}
else if( "delete" == command )
{
//删除指定的ITEM
if( !_bIsLogin )
{
cerr<<"please login first"<<endl;
}
else
{
int itemId;
cin>>itemId;
int iItemCount = _userInfo.seqItems.length();
bool bDeleted = false;
for( int i = 0; i<iItemCount; i++ )
{
if( _userInfo.seqItems[i].iItemId == itemId )
{
//删除改数据
for( int j=i;(j+1)<iItemCount;j++ )
{
//把后面的内容往前移
_userInfo.seqItems[j]=_userInfo.seqItems[j+1];
}
_userInfo.seqItems.length(iItemCount-1);//长度减少
bDeleted = true;
break;
}//end of if
}
if( bDeleted && _varEchoMgr->updateUserInfo( _userInfo ))
{
//提交到服务端
cout<<"delete success"<<endl;
}else
{
cout<<"delete failed"<<endl;
}
}//if _bIsLogin
}
else if( "clear" == command )
{
if( _bIsLogin )
{
_userInfo.seqItems.length(0);
if( _varEchoMgr->updateUserInfo( _userInfo ))
{
cerr<<"clear success"<<endl;
}else
{
cerr<<"clear failed"<<endl;
}
}else
{
cerr<<"please login first"<<endl;
}
}
else if( "logout" == command )
{
_bIsLogin = false;
system("cls"); //清屏
}
else if( "exit" == command )
{
exit(0);
}else
{
cerr<<"unkown command"<<endl;
}
}//while loop
}
catch(CORBA::SystemException&) {
cerr << "Caught a CORBA::SystemException." << endl;
}
catch(CORBA::Exception& e) {
cerr << e._info() << endl;
cerr << "Caught CORBA::Exception." << endl;
}
catch(...) {
cerr << "Caught unknown exception." << endl;
}
return 0;
}
void printHelp()
{
//打印帮助菜单
cout<<setw(15)<<setiosflags(ios::left)<<"help"<<"display help menu"<<endl;
cout<<setw(15)<<setiosflags(ios::left)<<"register"<<"[username] [password] "<<endl;
cout<<setw(15)<<setiosflags(ios::left)<<"login" <<"[username] [password]"<<endl;
cout<<setw(15)<<setiosflags(ios::left)<<"add" <<"[start] [end] [title]"<<endl;
cout<<setw(15)<<""<<"eg:add 2012/12/13 12:12:12 2012/12/14 12:12:12 title1"<<endl;
/*cout<<setw(15)<<"query" <<"[start] [end]"<<endl;*/
cout<<setw(15)<<setiosflags(ios::left)<<"querya" <<"queray all items"<<endl;
cout<<setw(15)<<setiosflags(ios::left)<<"delete" <<"[itemId]"<<endl;
cout<<setw(15)<<setiosflags(ios::left)<<"clear" <<"clear all time"<<endl;
cout<<setw(15)<<setiosflags(ios::left)<<"logout" <<endl;
cout<<setw(15)<<setiosflags(ios::left)<<"exit" <<"exit the system"<<endl;
}
客户端的配置参见服务端的配置。
注意:对于在IDL中定义out参数的结构体或对象,需要在服务端或者客户端初始化,否则空指针会出现运行错误。
5. 启动命名服务
cd %TAO_ROOT%/orbsvcs/Naming_Service/
tao_cosnaming -m 0 -ORBEndpoint iiop://127.0.0.1:10000
注意:如果tao_cosnaming不存在,请编译Naming_Service工程,然后会生成该可执行文件,其中127.0.0.1:10000是目的主机的IP和端口号,这里设为本地
6. 启动服务端
Server.exe -ORBInitRef NameService=iioploc://127.0.0.1:10000/NameService
7.启动客户端
Client.exe -ORBInitRef NameService=iioploc://127.0.0.1:10000/NameService