基于CORBA的分布式程序设计(九)

来源:互联网 发布:天使 vc pe 区别知乎 编辑:程序博客网 时间:2024/05/18 15:55

6.2 基于CORBA技术的聊天软件:

本程序实现了CORBATUXEDO的互连,为联创系统集成软件公司的数据网综合业务计费与管理系统(LICMS)与佳都国际软件公司的飞马系统的集成打好了技术基础。

该软件的接口定义(IDL)如下:

 

// Chat.idl

 

module Chat {

  typedef string User;

  typedef string Time;

 

  struct Message {

    User sender;

    User receiver;

    Time timestamp;

    string content;

  };

 

  typedef sequence<User> UserList;

  typedef sequence<Message> MessageList;

   

  interface ChatServer {

    short getOnlineUsers(out UserList onlineUsers);

    short getMessages(out MessageList msgList, in User regName);

    short registerUser(in User regName);

    short UnregisterUser(in User UnregName);

    short sendMessage(in Message sendMsg);

  };

};

 

该软件的服务器端Skeleton(骨架)定义如下:

 

// Server.cpp : Defines the entry point for the console application.

//

#include <iostream.h>

#include "ChatServerImpl.h"

#if defined(_VIS_STD)

# include <fstream>

#else

 

# include <fstream.h>

#endif

 

 

int main(int argc, char* const* argv)

{

  try {

    // Initialize the ORB.

    CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);

 

    // Get the property manager; notice the value returned

    // is not placed into a 'var' type.

    VISPropertyManager_ptr pm = orb->getPropertyManager();

    pm->addProperty("vbroker.se.mySe.scms", "scmlist");

   

    pm->addProperty("vbroker.se.mySe.scm.scmlist.manager.type", "Socket");

    pm->addProperty("vbroker.se.mySe.scm.scmlist.manager.connectionMax", (CORBA::ULong)100);

    pm->addProperty("vbroker.se.mySe.scm.scmlist.manager.connectionMaxIdle",

                    (CORBA::ULong)300);

   

    pm->addProperty("vbroker.se.mySe.scm.scmlist.listener.type", "IIOP");

    // We just add the Port host will be set to NULL

    // and will be filled with the default host

    pm->addProperty("vbroker.se.mySe.scm.scmlist.listener.port", (CORBA::ULong)55000);

    pm->addProperty("vbroker.se.mySe.scm.scmlist.listener.proxyPort", (CORBA::ULong)0);

   

    pm->addProperty("vbroker.se.mySe.scm.scmlist.dispatcher.type",

                    "ThreadPool");

    pm->addProperty("vbroker.se.mySe.scm.scmlist.dispatcher.threadMax", (CORBA::ULong)100);

    pm->addProperty("vbroker.se.mySe.scm.scmlist.dispatcher.threadMin", (CORBA::ULong)5);

    pm->addProperty("vbroker.se.mySe.scm.scmlist.dispatcher.threadMaxIdle",

                    (CORBA::ULong)300);

   

    // Get a reference to the root POA

    CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");

    PortableServer::POA_var rootPOA = PortableServer::POA::_narrow(obj);

 

    // Create the policies

    CORBA::Any_var seAny(new CORBA::Any);

    // The SERVER_ENGINE_POLICY_TYPE requires a sequence, even if

    // only one engine is being specified.

    CORBA::StringSequence_var engines = new CORBA::StringSequence(1UL);

    engines->length(1UL);

    engines[(CORBA::ULong)0] = CORBA::string_dup("mySe");

    seAny <<= engines;

 

    CORBA::PolicyList_var policies = new CORBA::PolicyList(2UL);

    policies->length(2UL);

    policies[(CORBA::ULong)0] = orb->create_policy(PortableServerExt::SERVER_ENGINE_POLICY_TYPE, seAny);

    policies[(CORBA::ULong)1] = rootPOA->create_lifespan_policy(PortableServer::PERSISTENT);

   

    // get the POA Manager

    PortableServer::POAManager_var poa_manager = rootPOA->the_POAManager();

    // Create our POA with our policies

    PortableServer::POA_var myPOA = rootPOA->create_POA("chat_server_poa",

                                                        poa_manager,

                                                        policies);

   

    // Create the servant

    ChatServerImpl managerServant;

   

    // Decide on the ID for the servant

    PortableServer::ObjectId_var managerId =

                           PortableServer::string_to_ObjectId("ChatServer");

 

    // Activate the servant with the ID on myPOA

    myPOA->activate_object_with_id(managerId, &managerServant);

   

    // Obtain the reference

    CORBA::Object_var ref = myPOA->servant_to_reference(&managerServant);

 

    CORBA::String_var string_ref = orb->object_to_string(ref.in());

    ofstream refFile("ref.dat");

    refFile << string_ref << endl;

    refFile.close();

/* 

    // Initialize the ORB.

    CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);

 

    // get a reference to the root POA

    CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");

    PortableServer::POA_var rootPOA = PortableServer::POA::_narrow(obj);

   

    CORBA::PolicyList policies;

    policies.length(1);

    policies[(CORBA::ULong)0] = rootPOA->create_lifespan_policy(

                                                PortableServer::PERSISTENT);

 

    // get the POA Manager

    PortableServer::POAManager_var poa_manager = rootPOA->the_POAManager();

 

    // Create myPOA with the right policies

    PortableServer::POA_var myPOA = rootPOA->create_POA("chat_server_poa",

                                                        poa_manager,

                                                        policies);

    // Create the servant

    ChatServerImpl managerServant;

 

    // Decide on the ID for the servant

    PortableServer::ObjectId_var managerId =

                           PortableServer::string_to_ObjectId("ChatServer");

 

    // Activate the servant with the ID on myPOA

    myPOA->activate_object_with_id(managerId, &managerServant);

*/   

    // Activate the POA manager

    poa_manager->activate();

   

    /// Wait for Incoming Requests

    cout << "managerServant Server ready" << endl;

    orb->run();

  }

  catch(const CORBA::Exception& e) {

    cerr << e << endl;

    return 1;

  }

  return 0;

}

 

该软件的客户端Stub(存根)定义如下:

 

// ORBClient.h

#if !defined corba_client_h_

#define corba_client_h_

 

#include "chat_c.h"

 

//USE_STD_NS

 

class corba_client{

 

private:

    CORBA::ORB_var orb;

//    PortableServer::ObjectId_var managerId;

 

    Chat::ChatServer_var chatserver;

 

    Chat::MessageList_var msglist;

    Chat::UserList_var usrlist;

 

    char username[40];

    int osagentport;

 

    static corba_client *_Manager;

    corba_client(int port,char* name);

 

public:

    static corba_client *GetInstance (int port,char* name);

    static void destroyInstance();

    ~corba_client();

 

    int corba_client::orb_init();

 

    int getOnlineUsers();

    int get_user_by_num(char * name,int message);

 

    int getMessages();

    int get_message_by_num(char * sender,char * receiver,char * timestamp,char * content,int num);

 

    int registerUser();

    int UnregisterUser();

    int sendMessage(const char* sender,const char* receiver,const char* content);

};

 

#endif // !defined corba_client_h_

 

 

 

 

 

//ORBClient.cpp

   

#include "stdafx.h"

#include "OrbClient.h"  

#include <fstream.h>

 

 

corba_client *corba_client::_Manager = 0;

 

corba_client::corba_client(int port,char* name){

    osagentport = port;

    strcpy(username,name);

}

 

corba_client::~corba_client(){

 

}

 

int corba_client::orb_init()

{

    cout<<"begin c++ orb_init"<<endl;

 

 

        int argc=3;

        char* argv[3];

        argv[0] = "Chat";

        argv[1] = "-ORBid";

        argv[2] = "BEA_IIOP";

 

  const int MAXBUF = 1024;

  char ior[MAXBUF];

 

  try {

    // Initialize the ORB.

    CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);

 

    // Default to checking

    CORBA::String_var fileName(CORBA::string_dup("ref.dat"));

 

    // Convert from string to object

    ifstream in(fileName);

    in.getline(ior, MAXBUF);

    CORBA::Object_var object = orb->string_to_object(ior);

 

    // Locate an account manager. Give the full POA name and the servant ID.

    chatserver = Chat::ChatServer::_narrow(object);

/*

        orb = CORBA::ORB_init(argc,argv);

        TimeBase::TimeT timeout = 20000000;

        CORBA::Any timeout_value;

        timeout_value <<= timeout;

        CORBA::Policy_var policy;

        policy = orb->create_policy(Messaging::RELATIVE_RT_TIMEOUT_POLICY_TYPE,timeout_value);

            cout<<"ok 1"<<endl;

           managerId = PortableServer::string_to_ObjectId("ChatServer");

            cout<<"ok 2"<<endl;

            chatserver = Chat::ChatServer::_bind("/chat_server_poa", managerId);

        CORBA::PolicyList policies;

        policies.length(1);

        policies[0] = CORBA::Policy::_duplicate(policy);

        CORBA::Object_var pmobj = orb->resolve_initial_references("ORBPolicyManager");

        CORBA::PolicyManager_var orb_mgr = CORBA::PolicyManager::_narrow(pmobj);

        orb_mgr->set_policy_overrides(policies, CORBA::SET_OVERRIDE);

           cout<<"end c++ init"<<endl;

*/

    }

    catch(CORBA::OBJECT_NOT_EXIST& e)

    {

        cout << "Chat Server is not start up!" <<endl;

        return -1;

    }

    catch (CORBA::Exception& e)

    {

        cout << "CORBA exception : " << e.get_id() << endl;

        return -1;

    }

    catch(...){

      cout << "There are some Unknown error while inititial ORB"<<endl;

      return -1;

    }

 

    return 0;

}

 

corba_client * corba_client::GetInstance (int port,char* name) {

    if (!_Manager)

    {

        _Manager = new corba_client(port,name);

#ifdef _DEBUG

        cout << " new corba_client " << endl;

#endif

    }

    return _Manager;

}

 

void corba_client::destroyInstance(){

#ifdef _DEBUG

        cout << " delete corba_client " << endl;

#endif

    if (_Manager)

            delete _Manager;

    _Manager = 0;

}

 

int corba_client::getOnlineUsers() {

    if((Chat::ChatServer_ptr)chatserver == NULL)

        return -1;

 

    int i;

 

    try{

        cout<<"start getOnlineUsers..."<<endl;

        if((Chat::ChatServer_ptr)chatserver != NULL)

            i=chatserver->getOnlineUsers(usrlist);

        cout<<"end getOnlineUsers..."<<endl;

    }

    catch(CORBA::Exception &e)

    {

        cerr << e.get_id() << endl;

        i=-2;

    }

    return i;

}

 

int corba_client::get_user_by_num(char * name,int num)

{

    if (num < 0 || num > usrlist->length())

        return -1;

 

    if((Chat::ChatServer_ptr)chatserver != NULL){

        Chat::UserList::_ForSeq_var*  item = &((*usrlist)[num]);

        strcpy(name,*item); // ??

    }

   

    return 0;

}

 

int corba_client::getMessages() {

    if((Chat::ChatServer_ptr)chatserver == NULL)

        return -1;

 

    int i;

 

    try{

        cout<<"start getMessages..."<<endl;

        if((Chat::ChatServer_ptr)chatserver != NULL)

            i=chatserver->getMessages(msglist,username);

        cout<<"end getMessages..."<<endl;

    }

    catch(CORBA::Exception &e)

    {

        cerr << e.get_id() << endl;

        i=-2;

    }

    return i;

}

 

int corba_client::get_message_by_num(char * sender,char * receiver,char * timestamp,char * content,int num)

{

    if (num < 0 || num > msglist->length())

        return -1;

 

    if((Chat::ChatServer_ptr)chatserver != NULL){

        Chat::Message * item = &((*msglist)[num]);

        strcpy(sender,item->sender);

        strcpy(receiver,item->receiver);

        strcpy(timestamp,item->timestamp);

        strcpy(content,item->content);

    }

   

    return 0;

}

 

int corba_client::registerUser()

{

    if((Chat::ChatServer_ptr)chatserver == NULL)

        return -1;

 

    int i;

    try{

        i=chatserver->registerUser(username);

    }

    catch(CORBA::Exception &e)

    {

        cerr << e.get_id() << endl;

        i=-2;

    }

    return i;

}

 

int corba_client::UnregisterUser()

{

    if((Chat::ChatServer_ptr)chatserver == NULL)

        return -1;

 

    int i;

    try{

        i=chatserver->UnregisterUser(username);

    }

    catch(CORBA::Exception &e)

    {

        cerr << e.get_id() << endl;

        i=-2;

    }

    return i;

}

 

int  corba_client::sendMessage(const char* sender,const char* receiver,const char* content)

{

    if((Chat::ChatServer_ptr)chatserver == NULL)

        return -1;

 

    int i;

    try{

        Chat::Message msg;

        msg.sender = CORBA::string_dup(sender);

        msg.receiver = CORBA::string_dup(receiver);

        msg.content = CORBA::string_dup(content);

        i = chatserver->sendMessage(msg);

    }

    catch(CORBA::Exception &e)

    {

        cerr << e.get_id() << endl;

        i=-2;

    }

    return i;

}

 

 

本软件的开发环境使用了Visual C++、VIsiBroker版本的CORBA中间件产品和Tuxedo 8.1

软件除了具备发送消息、接收消息等基础的功能外,还实现了查看在线用户、群发消息、收发中文消息等许多功能,并解决了头疼的中文消息互发问题。


 

 

原创粉丝点击