Таблица 4. Файл Server/CServiceARunner.h Server/CServiceARunner.h
#ifndef CSERVICEARUNNER_H #define CSERVICEARUNNER_H
#include "../Data.hh" #include "CServiceA.h" class CServiceARunner
{
public:
CServiceARunner(int argc, char **argv); ~CServiceARunner();
void run(); CORBA::String_var get_ior();
private:
//Брокер объектных запросов (Object Request Broker, ORB) CORBA::ORB_var m_orb;
//Сервант
PortableServer::Servant_var<CServiceA_i> m_c_service_a;
//Строковая IOR ссылка на объект-сервант
CORBA::String_var m_ior;
//POA
PortableServer::POA_var m_poa; // RootPOA
CORBA::Object_var m_root_poa_obj; // POA менеджер
PortableServer::POAManager_var poa_manager; // ObjectID
PortableServer::ObjectId_var m_c_service_a_oid;
};
#endif // CSERVICEARUNNER_H
Таблица 5. Файл Server/CServiceARunner.cpp Server/CServiceARunner.cpp
#include "CServiceARunner.h" #include "CServiceA.h" #include "../Data.hh"
#include <utility> #include <iostream>
CServiceARunner::CServiceARunner(int argc, char **argv)
{
//Инициализация брокера объектных запросов
//(Object Request Broker, ORB)
m_orb = CORBA::ORB_init(argc, argv); if (CORBA::is_nil(m_orb))
{
throw std::runtime_error("CORBA::ORB_init failed.");
}
//Получение доступа к переносимому объектному адаптеру по умолчанию
//(Root Portable Object Adapter, RootPOA)
m_root_poa_obj = m_orb->resolve_initial_references("RootPOA"); if (CORBA::is_nil(m_root_poa_obj))
{
throw std::runtime_error("CORBA::ORB->resolve_initial_references(\"RootPOA\") failed.");
}
m_poa = PortableServer::POA::_narrow(m_root_poa_obj); if (CORBA::is_nil(m_poa))
{
throw std::runtime_error("PortableServer::POA::_narrow failed.");
}
PortableServer::POAManager_var poa_manager = m_poa->the_POAManager(); if (CORBA::is_nil(poa_manager))
{
throw std::runtime_error("PortableServer::POA->the_POAManager() failed.");
}
// Создание серванта m_c_service_a = new CServiceA_i();
// Активация серванта в RootPOA (переносимом объектном адаптере по умолчанию)
6
Server/CServiceARunner.cpp
m_c_service_a_oid = m_poa->activate_object(m_c_service_a);
//Запоминание строковой IOR ссылки на объект-сервант
//(Interoperable Object Reference, IOR)
m_ior = m_orb->object_to_string(m_c_service_a->_this()); // Получение корневого контекста именования
CORBA::Object_var name_service_obj = m_orb->resolve_initial_references("NameService"); if (CORBA::is_nil(name_service_obj))
{
throw std::runtime_error("CORBA::ORB->resolve_initial_references(\"NameService\") failed.");
}
CosNaming::NamingContext_var naming_context = CosNaming::NamingContext::_narrow(name_service_obj); if (CORBA::is_nil(naming_context))
{
throw std::runtime_error("CosNaming::NamingContext::_narrow failed.");
}
//Привязка к службе имен CORBA CosNaming::Name name; name.length(1);
name[0].id = "DataService"; name[0].kind = "Context";
naming_context->rebind(name, m_c_service_a->_this());
//Активация POA Manager
poa_manager->activate();
}
CServiceARunner::~CServiceARunner()
{
try
{
m_orb->destroy(); // Уничтожение объекта ORB
}
catch (...)
{
std::cerr << "CORBA::ORB->destroy exception occurred." << std::endl;
}
}
void CServiceARunner::run()
{
m_orb->run();
}
CORBA::String_var CServiceARunner::get_ior()
{
return m_ior;
}
Таблица 6. Файл Server/Server.cpp Server/Server.cpp
#include <iostream>
#include "CServiceARunner.h" #include "../Data.hh"
int main(int argc, char **argv)
{
CServiceARunner runner(argc, argv); std::cout << runner.get_ior() << std::endl; runner.run();
return 0;
}
7
Клиентская часть проекта состоит из 3 файлов:
1.Client/CRequestServiceA.h и Client/CRequestServiceA.cpp (см. таблицы
7-8) содержат класс, используемый для инициализации брокера объектных запросов и запуска сервисов.
2.Client/Client.cpp (см. таблицу 9) описывает работу точки входа.
Таблица 7. Файл Client/CRequestServiceA.h Client/CRequestServiceA.h
#ifndef CREQUESTSERVICEA_H #define CREQUESTSERVICEA_H
#include <utility> #include "../Data.hh"
class CRequestServiceA
{
public:
CRequestServiceA(int argc, char **argv); ~CRequestServiceA();
CORBA::String_var RequestHelloWorld(CORBA::String_var); std::pair<CORBA::Long, bool> RequestDiv(CORBA::Long, CORBA::Long); CORBA::String_var RequestCaesarCipher(CORBA::String_var, CORBA::Short);
private:
//Объект, связанный с брокером объектных запросов (Object Request Broker, ORB)
CORBA::ORB_var m_orb;
//Объект посредством которого осуществляются запросы
Data::ServiceA_var m_obj;
};
#endif // CREQUESTSERVICEA_H
Таблица 8. Файл Client/CRequestServiceA.cpp Client/CRequestServiceA.cpp
#include <stdexcept> #include <iostream> #include <utility>
#include "CRequestServiceA.h" #include "../Data.hh"
CRequestServiceA::CRequestServiceA(int argc, char **argv)
{
//Инициализация брокера объектных запросов (Object Request Broker, ORB) m_orb = CORBA::ORB_init(argc, argv);
if (CORBA::is_nil(m_orb))
{
throw std::runtime_error("CORBA::ORB_init failed.");
}
//Получение корневого контекста именования
CORBA::Object_var ns_obj = m_orb->resolve_initial_references("NameService"); if (CORBA::is_nil(ns_obj))
{
throw std::runtime_error("CORBA::ORB->resolve_initial_references failed.");
}
CosNaming::NamingContext_var nc = CosNaming::NamingContext::_narrow(ns_obj); if (CORBA::is_nil(nc))
{
throw std::runtime_error("CosNaming::NamingContext::_narrow failed.");
}
// Получение доступа к серверу
CosNaming::Name name; name.length(1);
name[0].id = "DataService";
8
Client/CRequestServiceA.cpp
name[0].kind = "Context"; CORBA::Object_var obj = nc->resolve(name); if (CORBA::is_nil(obj))
{
throw std::runtime_error("CosNaming::NamingContext->resolve failed.");
}
// Получение доступа к запрашиваемому объекту m_obj = Data::ServiceA::_narrow(obj);
if (CORBA::is_nil(obj))
{
throw std::runtime_error("Data::ServiceA::_narrow failed.");
}
}
CRequestServiceA::~CRequestServiceA()
{
try
{
m_orb->destroy(); // Уничтожение объекта ORB
}
catch (...)
{
std::cerr << "Orb destroy exception occurred." << std::endl;
}
}
CORBA::String_var CRequestServiceA::RequestHelloWorld(CORBA::String_var message_svar)
{
return m_obj->HelloWorld(message_svar);
}
std::pair<CORBA::Long, bool> CRequestServiceA::RequestDiv(CORBA::Long a, CORBA::Long b)
{
CORBA::Long c = 0;
CORBA::Boolean response = m_obj->Div(a, b, c); return {c, response};
}
CORBA::String_var CRequestServiceA::RequestCaesarCipher(CORBA::String_var message_svar, CORBA::Short k)
{
CORBA::String_INOUT_arg str(message_svar); m_obj->CaesarCipher(str, k);
return CORBA::string_dup(str);
}
Таблица 9. Файл Client/Client.cpp Client/Client.cpp
#include "CRequestServiceA.h" #include <iostream>
int main(int argc, char **argv)
{
//В конструкторе устанавливается связь с сервером CORBA
CRequestServiceA requestServiceA(argc, argv);
//Отправка запросов, получение и вывод ответов
auto responseHelloWorld = requestServiceA.RequestHelloWorld("Hello"); auto responseDiv = requestServiceA.RequestDiv(10, 5);
auto responseCaesarCipher = requestServiceA.RequestCaesarCipher("Hello, world!", 3); std::cout << "Response (HelloWorld): " << responseHelloWorld << std::endl;
std::cout << "Response (Div, 10/2): " << responseDiv.first << " (div error: " << !responseDiv.second << ')' << std::endl;
std::cout << "Response (CaesarCipher): " << responseCaesarCipher << std::endl; return 0;
}
9
Сборочный файл представлен в табл. 10.
Таблица 10. Сборочный файл Makefile Makefile
.PHONY : all clean_all clean CC=g++
CPPFLAGS=-std=c++11 -g -Werror -pedantic-errors -Wredundant-decls \ -Wall -Wextra -Wpedantic -Wcast-align -Wcast-qual \ -Wconversion -Wctor-dtor-privacy -Wduplicated-branches \ -Wduplicated-cond -Wextra-semi -Wfloat-equal -Wlogical-op \
-Wnon-virtual-dtor -Woverloaded-virtual -Wsign-conversion -Wsign-promo OMNI_HOME=/opt
INCLUDES=-I$(OMNI_HOME)/include LIBS=-lomniORB4 -lomnithread -lomniDynamic4 SERVER_SOURCES=$(wildcard ./Server/*.cpp) CLIENT_SOURCES=$(wildcard ./Client/*.cpp) SERVER_OBJECTS=$(SERVER_SOURCES:.cpp=.o) CLIENT_OBJECTS=$(CLIENT_SOURCES:.cpp=.o) SERVER_RUN=ServerRun
CLIENT_RUN=ClientRun
all: $(SERVER_RUN) $(CLIENT_RUN)
$(SERVER_RUN): DataSK.o $(SERVER_OBJECTS)
$(CC) -g -o $(SERVER_RUN) -L$(OMNI_HOME)/lib DataSK.o $(SERVER_OBJECTS) $(LIBS)
$(SERVER_OBJECTS): DataSK.o $(SERVER_SOURCES)
$(foreach src,$(SERVER_SOURCES),$(CC) $(CPPFLAGS) -c $(src) -o $(src:.cpp=.o) &&) true
$(CLIENT_RUN): DataSK.o $(CLIENT_OBJECTS)
$(CC) -g -o $(CLIENT_RUN) -L$(OMNI_HOME)/lib DataSK.o $(CLIENT_OBJECTS) $(LIBS)
$(CLIENT_OBJECTS): DataSK.o $(CLIENT_SOURCES)
$(foreach src,$(CLIENT_SOURCES),$(CC) $(CPPFLAGS) -c $(src) -o $(src:.cpp=.o) &&) true
DataSK.o: DataSK.cc Data.hh
$(CC) -c DataSK.cc
DataSK.cc Data.hh: Data.idl
omniidl -bcxx Data.idl
clean_all: clean
rm -f ./$(SERVER_RUN) rm -f ./$(CLIENT_RUN)
clean:
rm -f ./*.o rm -f ./*.hh rm -f ./*SK.cc
rm -f ./Server/*.o rm -f ./Client/*.o
10