2 Stimmen

CORBA Client/Server-Anwendung, Abrufen von Informationen vom Server (Nullwerte)

Ich habe eine einfache Anwendung in Java und C++ in CORBA erstellt, eine Client-Server-Anwendung, sehen Sie sich das an:

interface Task
{
    string getThingToDo();
};

#include "Task.idl"

interface Employee
{
    typedef sequence <Task> tasks;
    string getLastname();
    Task getTask(in short id);
};

#include "Employee.idl"

interface Work
{
    Employee getEmployee(in short id);
};

TaskImpl.h y TaskImpl.cpp:

#include "Task.hh"

class TaskImpl : public POA_Task
{
    private:
        CORBA::String_var thingToDo;

    public:
        TaskImpl(const char* thingToDo);
        char* getThingToDo();
};

#include "TaskImpl.h"

TaskImpl::TaskImpl(const char* thingToDo)
{
    this->thingToDo = CORBA::string_dup(thingToDo);
}

char* TaskImpl::getThingToDo()
{
    return CORBA::string_dup(this->thingToDo.in());
}

EmployeeImpl.h y EmployeeImpl.cpp:

#include "Employee.hh"
#include "TaskImpl.h"

class EmployeeImpl : public POA_Employee
{
    private:
        CORBA::String_var lastname;
        int id;
        Employee::tasks thingsToDo;

    public:
        EmployeeImpl(const char* lastname, int id);
        char* getLastname();
        Task_ptr getTask(::CORBA::Short id);
};

#include "EmployeeImpl.h"

EmployeeImpl::EmployeeImpl(const char* lastname, int id)
{
    this->lastname = CORBA::string_dup(lastname);
    this->id = id;
    this->thingsToDo.length(3);

    TaskImpl *t1, *t2, *t3;
    t1 = new TaskImpl("Print all the documents");
    t2 = new TaskImpl("Write the report");
    t3 = new TaskImpl("Make backup");

    this->thingsToDo[0] = t1->_this();
    this->thingsToDo[1] = t2->_this();
    this->thingsToDo[2] = t3->_this();
}

char* EmployeeImpl::getLastname()
{
    return CORBA::string_dup(this->lastname.in());
}

Task_ptr EmployeeImpl::getTask(::CORBA::Short id)
{
    return Task::_duplicate(this->thingsToDo[id-1]);
}

WorkImpl.h y WorkImpl.cpp:

#include "Work.hh"
#include <vector>
#include "EmployeeImpl.h"
using namespace std;

class WorkImpl : public POA_Work
{
    private:
        vector<EmployeeImpl> employees;

    public:
        WorkImpl();
        Employee_ptr getEmployee(::CORBA::Short id);
};
#include "WorkImpl.h"

 WorkImpl::WorkImpl()
 {
    EmployeeImpl ei1(CORBA::string_dup("Doe"), 1);
    EmployeeImpl ei2(CORBA::string_dup("Smith"), 2);
    EmployeeImpl ei3(CORBA::string_dup("Brown"), 3);

    employees.push_back(ei1);
    employees.push_back(ei2);
    employees.push_back(ei3);
 }

Employee_ptr WorkImpl::getEmployee(::CORBA::Short id)
{
    return employees[id]._this();
}

Server.cpp:

#include "WorkImpl.h"
#include <omniORB4/CORBA.h>
#include <omniORB4/Naming.hh>
#include <iostream>
using std::cout;
using std::cerr;

int main(int argc, char **argv)
{
 try
 {
  CORBA::ORB_ptr serverORB = CORBA::ORB_init(argc, argv);

  CORBA::Object_var myPOAObj = serverORB->resolve_initial_references("RootPOA");

  PortableServer::POA_var myPOA = PortableServer::POA::_narrow(myPOAObj);
  PortableServer::POAManager_var myManager = myPOA->the_POAManager();
  myManager->activate();

  WorkImpl *work = new WorkImpl();

  try
  {
   CORBA::Object_var nameServiceObj = serverORB->resolve_initial_references("NameService");

   if(!CORBA::is_nil(nameServiceObj))
   {
    CosNaming::NamingContext_ptr namingContext = CosNaming::NamingContext::_narrow(nameServiceObj);
    CosNaming::Name serviceName;
    serviceName.length(1);
    serviceName[0].id = CORBA::string_dup("WorkService");
    namingContext->rebind(serviceName, work->_this());
    cout << "WorkService is running ...\n";
   }

  }catch(CosNaming::NamingContext::NotFound&){
      cerr << "CosNaming::NamingContext::NotFound\n";
  }catch(CosNaming::NamingContext::InvalidName&){
      cerr << "CosNaming::NamingContext::InvalidName\n";
  }catch(CosNaming::NamingContext::CannotProceed&){
      cerr << "CosNaming::NamingContext::CannotProceed\n";
  }

  serverORB->run();

  delete work;
  serverORB->destroy();

  }catch(CORBA::SystemException&){
    cerr << "Caught CORBA::SystemException\n";
  }catch(CORBA::Exception&){
    cerr << "Caught CORBA::Exception  \n";
  }catch(omniORB::fatalException &fe){
    cerr << "Caught omniORB::fatalException\n";
    cerr << "File: " << fe.file() << "\n";
    cerr << "Line: " << fe.line() << "\n";
    cerr << "Msg: " << fe.errmsg() << "\n";
  }catch(...){
    cerr << "Caught unknown exception\n";
  }

   return 0;
}

Client.java:

package OtherPackage;

import java.util.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;
import java.io.*;
public class Client
{
    public static void main(String [] args)
    {
     try
     {
        org.omg.CORBA.ORB clientORB = org.omg.CORBA.ORB.init(args, null);

        if (clientORB == null)
        {
            System.out.println("Problem while creating ORB");
            System.exit(1);
        }

        org.omg.CORBA.Object objRef = clientORB.resolve_initial_references("NameService");
        NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);

        Work work = WorkHelper.narrow(ncRef.resolve_str("WorkService"));
        Employee e = work.getEmployee((short)1);
        System.out.println(e.getLastname());
        Task t = e.getTask((short)1);
        System.out.println(t.getThingToDo());

        }catch(Exception e){ System.out.println(e.getMessage()); 
            }
    }
}

Als ich die EmployeeImpl.cpp wie diese:

#include "EmployeeImpl.h"

EmployeeImpl::EmployeeImpl(const char* lastname, int id)
{
    this->lastname = CORBA::string_dup(lastname);
    this->id = id;
    this->thingsToDo.length(3);

    TaskImpl *t1, *t2, *t3;
    t1 = new TaskImpl("Print all the documents");
    t2 = new TaskImpl("Write the report");
    t3 = new TaskImpl("Make backup");

    this->thingsToDo[0] = Task::_duplicate(t1->_this());
    this->thingsToDo[1] = Task::_duplicate(t2->_this());
    this->thingsToDo[2] = Task::_duplicate(t3->_this());
}

char* EmployeeImpl::getLastname()
{
    return CORBA::string_dup(this->lastname.in());
}

Task_ptr EmployeeImpl::getTask(::CORBA::Short id)
{
    return this->thingsToDo[id-1]._retn();
}

und ich habe den Kunden zum ersten Mal gesehen:

Smith
Print all the documents

was korrekt ist. Aber als ich meinen Client zum zweiten (und dritten, und so weiter ...) Mal ausgeführt habe, habe ich gesehen:

Smith
null

Wo liegt das Problem? Ich habe viel darüber nachgedacht und schrieb EmployeeImpl.cpp wieder:

#include "EmployeeImpl.h"

EmployeeImpl::EmployeeImpl(const char* lastname, int id)
{
    this->lastname = CORBA::string_dup(lastname);
    this->id = id;
    this->thingsToDo.length(3);

    TaskImpl *t1, *t2, *t3;
    t1 = new TaskImpl("Print all the documents");
    t2 = new TaskImpl("Write the report");
    t3 = new TaskImpl("Make backup");

    this->thingsToDo[0] = t1->_this();
    this->thingsToDo[1] = t2->_this();
    this->thingsToDo[2] = t3->_this();
}

char* EmployeeImpl::getLastname()
{
    return CORBA::string_dup(this->lastname.in());
}

Task_ptr EmployeeImpl::getTask(::CORBA::Short id)
{
    return Task::_duplicate(this->thingsToDo[id-1]);
}

und jetzt scheint alles gut zu sein, jedes Mal, wenn ich den Client ausführe. Aber ich bin nicht sicher, ob es gut ist in CORBA Weg. Irgendwelche Vorschläge?

Verwenden Sie diese Befehle, um Server- und Client-Dateien zu kompilieren und auszuführen (ich verwende omniORB 4.1.6 und das Paket default-jdk auf Kubuntu 12.04):

Compile (and run) server files (just copy and paste):

g++ -c *.cpp -I$OMNIORB_HOME/include -I$OMNIORB_HOME/include/omniORB4
g++ -c *.cc -I$OMNIORB_HOME/include -I$OMNIORB_HOME/include/omniORB4
g++ -o Server Server.o EmployeeSK.o WorkSK.o WorkImpl.o EmployeeImpl.o TaskImpl.o TaskSK.o -L$OMNIORB_HOME/lib -lomnithread -lomniORB4
./Server -ORBInitRef NameService=corbaloc::localhost:2809/NameService

Compile (and run) client files (just copy and paste):

cd EmployeePackage; javac -cp .. *.java
cd OtherPackage; javac -cp .. *.java
cd java; java OtherPackage.Client -ORBInitRef NameService=corbaloc::localhost:2809/NameService

Hier ist mein Arbeitscode: http://www9.zippyshare.com/v/46287610/file.html

3voto

Brian Neal Punkte 30564

Wenn ich es mir recht überlege, bin ich mir nicht sicher, ob meine Antwort wirklich richtig war, und bei Stackoverflow kann ich meine Antwort nicht mehr löschen, sobald sie akzeptiert wurde.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X