源碼下載: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