Технология CORBA
Создание клиент-серверного приложения на основе технологии CORBA. Проектирование многоуровневой системы, в которой клиент при помощи банкомата выполняет необходимые операции. Способы реализации серверов в разных каналах для ускорения обработки данных.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | лабораторная работа |
Язык | русский |
Дата добавления | 08.06.2009 |
Размер файла | 1,1 M |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Лабораторная работа:
Технология CORBA
Пример 1. Тестирование CORBA-соединения клиента с сервером
Рассмотрим создание примитивной клиент/серверной ИС, состоящей из:
· CORBA-сервера, приветствующего обратившегося к нему CORBA-клиента;
· CORBA-клиента, способного подключаться к CORBA-серверу.
Построение CORBA-сервера
Для построения CORBA-сервера нужно запустить мастера CORBA Server командой File | New | Other | Multitier | CORBA Server (рис. 1).
Рисунок 1
Когда мастер создания сервера запущен, он ожидает от программиста некоторой дополнительной информации (рис. 2):
1. Какого рода CORBA-сервер следует создать: консольное приложение (опция Console Application) или оконное (Window Application)? Не лишне напомнить, что сервер CORBA - это программа, производящая экземпляры объектов и уведомляющая об этом все заинтересованные программы-клиенты.
Рисунок 2
2. Имена IDL-файлов с описанием интерфейсов объектов (кнопка Add) либо, если отметить кнопку Add New IDL File, мастер сам создаст пустой IDL-файл и добавит его в проект.
После нажатия кнопки OK генерируется новый проект, и в окне редактора открывается пустой IDL-файл.
Следующим действием разработчика будет описание интерфейса объекта калькулятора на языке IDL (рис. 5.3).
Рисунок 3
Сохраним полученное описание в файле с именем User.idl.
Теперь можно создать интерфейс пользователя, как показано на рис. 4.
Рисунок 4
В элемент управления Memo1 будет заноситься строка приветствия подключившегося к CORBA-серверу клиента.
Сохраним проект под именем CORBAServerProject.
Для создания импортируемого сервером объекта выполним команду File | New | Other | Multitier | CORBA Object Implementation для запуска соответствующего мастера (рис. 5).
Рисунок 5
Запущенный мастер собирает необходимую для генерации кода информацию (название файла описания объекта на IDL и имя реализуемого интерфейса) и отбражает на экране диалоговое окно (рис. 5.6).
.
Рисунок 6
В поле Interface Name следует выбрать из выпадающего списка имя интерфейса User::Welcome; это приведет к автоматическому заполнению имени класса объекта и модуля, которые будут сгенерированы мастером CORBA Object Implementation. Имя самого объекта WelcomeObject проставляется в поле Object Names. В самом низу диалоговой панели в левой ее стороне находится кнопка Show Updates. Со включенной кнопкой Show Updates программист получает возможность видеть все изменения в проекте, происходящие при генерации новых файлов и автоматической модификации уже имеющихся исходных текстов. После нажатия на кнопку Ok появляется окно (рис. 7), в котором слева отображается список всех произошедших во время работы мастера действий, тогда как в правой панели находятся исходные тексты, являющиеся результатом подобных действий.
Рисунок 7
Эта панель - полноценный редактор, в котором можно тут же внести изменения. Если то или иное действие мастера программиста не устраивает, он может просто отключить кнопку напротив его названия в левой панели. И действие будет отменено. Создавая калькулятор, нужно найти действие с именем WelcomeImpl::Hello (в левой панели), переключиться на него и внутрь пока еще пустого (в правой панели) метода Hello внести код приветствия. Заметим, что для успешной компиляции этого кода в модуль нужно добавить заголовочный файл формы #include "CORBAServerUnit.h", а ссылку extern TForm1 *Form1;.
Осталось построить проект (рис. 8).
Рисунок 8
CORBAServerProject.cpp
#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
#include "WelcomeServer.h"
#include <corba.h>
USEFORM("CORBAServerUnit.cpp", Form1);
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
Application->Initialize();
// Initialize the ORB and BOA
CORBA::ORB_var orb = CORBA::ORB_init(__argc, __argv);
CORBA::BOA_var boa = orb->BOA_init(__argc, __argv);
WelcomeImpl welcome_WelcomeObject("WelcomeObject");
boa->obj_is_ready(&welcome_WelcomeObject);
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
catch (...)
{
try
{
throw Exception("");
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
}
return 0;
}
WelcomeServer.cpp
#pragma hdrstop
#include <corba.h>
#include "WelcomeServer.h"
#include "CORBAServerUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
extern TForm1 *Form1;
WelcomeImpl::WelcomeImpl(const char *object_name):
_sk_User::_sk_Welcome(object_name)
{
}
void WelcomeImpl::Hello()
{
Form1->Memo1->Lines->Add ("Hello, client!");
}
Интересной особенностью CORBA-мастеров C++ Builder является их умение синхронизировать изменения в описании объектной модели с генерируемыми исходными текстами. Каждый раз, когда программист модифицирует IDL-файл, среда разработки исправляет заглушки (stubs) и скелеты (skeletons) приложения, а также переделывает объект.
Построение CORBA-клиента
Действия, необходимые для проектирования клиентского приложения, обращающегося к серверу, также не сложны.
Для построения CORBA-клиента нужно запустить мастера CORBA Client командой File | New | Other | Multitier | CORBA Server (рис. 5.9).
Рисунок 9
В появившемся диалоговом окне (рис. 5.10) нужно выбрать тип приложения и ввести имя IDL-файла user.idl, описывающего объект, к которому будет обращаться CORBA-клиент (можно и не указывать этого имени, а просто добавить IDL-файл в проект).
Рисунок 10
Далее нужно спроектировать несложный интерфейс пользователя, позволяющий соединяться с CORBA-сервером (рис. 11).
Рисунок 11
#include <vcl.h>
#pragma hdrstop
#include "CORBAClientUnit.h"
#include "user_c.hh" // !!!
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2 *Form2;
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Button1Click(TObject *Sender)
{
User::Welcome_var H = User::Welcome::_bind("WelcomeObject");
H->Hello();
}
В обработчике нажатия на кнопку «Подключение к CORBA-серверу» помещают исходный текст, производящий вызов метода Hello() удаленного объекта WelcomeObject интерфейса Welcome модуля User.
Тестирование ИС
Для тестирования ИС следует активизировать утилиту Smart Agent из меню Tools (это программа c:\Inprise\vbroker\bin\osagent.exe) (рис. 12).
Рисунок 12
и последовательно (вне среды C++ Builder) запустить CORBA-сервер и CORBA-клиент
Пример 2. Создание многоуровневой ИС
Рассмотрим пример создания многоуровневой ИС, в которой клиент из банкомата может обратиться к серверу банка и выполнить нужные ему операции (рис. 15).
Рисунок 15
Для ускорения обработки данных серверы банков реализованы в разных каналах.
Пример следует рассмотреть самостоятельно, руководствуясь комментариями к нижеприведенному коду программы.
Xaction.idl
enum EnumAction {
balance,
withdraw,
deposit
};
enum EnumStatus {
OK,
invalid,
complete,
incomplete
};
struct xaction {
long UserID;
long PIN;
long account;
double amount;
::EnumAction action;
double balance;
::EnumStatus status;
};
interface Server {
exception NoServer {
string message;
};
::xaction HandleTransaction(
inout ::xaction Transaction
);
/* raises(
::Server::NoServer
);
*/
long Balance();
};
banking.idl
#include "xaction.idl"
interface BankServer {
::xaction HandleTransaction(
inout ::xaction Transaction
);
long BankID();
};
module Bank {
interface Account {
float balance();
};
interface AccountManager {
::Bank::Account open(
in string name
);
};
};
Рисунок 16. Проект и интерфейс банкомата
Рисунок 17. Режим «Администрирование»
ATMUnit/h
//---------------------------------------------------------------------------
#ifndef atmunitH
#define atmunitH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
#include <ComCtrls.hpp>
#include <Buttons.hpp>
//---------------------------------------------------------------------------
class ATMObject
{
private:
long _ID;
String _serverName;
public:
ATMObject(){_serverName = "Wells Fargo"; _ID = 100;};
ATMObject(String name){_serverName = name; _ID = 100;};
String serverName(){return _serverName;}
void serverName(String name){_serverName = name;}
long ID(){return _ID;}
void ID(long id){_ID = id;}
};
class TFormATM : public TForm
{
__published: // IDE-managed Components
TEdit *NameBox;
TEdit *PINBox;
TEdit *AmountBox;
TLabel *Label1;
TLabel *Label2;
TLabel *Label3;
TRadioGroup *Action;
TMemo *Memo1;
TRadioGroup *AccountType;
TStatusBar *StatusBar1;
TBitBtn *BitBtn1;
TBitBtn *BitBtn2;
TGroupBox *GroupBox1;
TGroupBox *GroupBox2;
TBitBtn *BitBtn3;
TLabel *Label4;
TLabel *Label5;
TBevel *Bevel1;
void __fastcall FormCreate(TObject/* */ *Sender);
void __fastcall BitBtn1Click(TObject *Sender);
void __fastcall BitBtn2Click(TObject *Sender);
void __fastcall BitBtn3Click(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TFormATM(TComponent* Owner);
ATMObject * ATM;
long __fastcall TestConnection();
};
//---------------------------------------------------------------------------
extern PACKAGE TFormATM *FormATM;
//---------------------------------------------------------------------------
#endif
ATMUnit.cpp
#include <vcl.h>
#pragma hdrstop
#include "atmunit.h"
#include "servname.h"
#include "xaction_c.hh"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
USE_STD_NS
TFormATM *FormATM;
//---------------------------------------------------------------------------
__fastcall TFormATM::TFormATM(TComponent* Owner)
: TForm(Owner)
{
}
char * const * argV;
int argC;
//---------------------------------------------------------------------------
// /////////////////////////////////////
// Mimic streaming to VCL Memo Window
// /////////////////////////////////////
class catchit: public streambuf
{
TMemo * M;
int ct;
String S;
char * cbuff;
public:
catchit(TMemo *Memo){M = Memo; ct = 1;};
int sync();
int overflow(int ch);
};
int catchit::overflow(int ch)
{
S += (char)ch;
return 0;
}
int catchit::sync()
{
// M->Lines->Strings[ct++] = S;
M->Lines->Add(S);
S = "";
return ct;
}
// ////////////////////////////////////////////
// class _update
// Instantiate this object to interface with the view
// Usage: new _update(FormATM);
// ////////////////////////////////////////////
class _update
{
private:
TFormATM * theForm;
public:
__fastcall _update(TFormATM* ATMForm)
{
theForm = ATMForm;
}
long AccountType()
{
return (long)theForm->AccountType->ItemIndex + 1;
}
EnumAction ActionType()
{
return (EnumAction)theForm->Action->ItemIndex;
}
long UserID()
{
if (theForm->NameBox->Text == "John") return 0;
if (theForm->NameBox->Text == "Bill") return 1;
if (theForm->NameBox->Text == "Jim") return 2;
if (theForm->NameBox->Text == "Gene") return 3;
if (theForm->NameBox->Text == "Wally") return 4;
if (theForm->NameBox->Text == "Frank") return 5;
return -1; // неизвестный пользователь
}
long PIN()
{ try {
return (long)theForm->PINBox->Text.ToInt();
} catch (Exception &e) {
return (long)0;
}
}
double Amount()
{
return theForm->AmountBox->Text.ToDouble();
}
void UpdateList()
{ theForm->Memo1->Lines->Clear();
theForm->Memo1->Lines->Add("John, PIN:123, Bank 1");
theForm->Memo1->Lines->Add("Bill, PIN:456, Bank 1");
theForm->Memo1->Lines->Add("Jim, PIN:789, Bank 1");
theForm->Memo1->Lines->Add("Gene, PIN:123, Bank 2");
theForm->Memo1->Lines->Add("Wally, PIN:456, Bank 2");
theForm->Memo1->Lines->Add("Frank, PIN:789, Bank 2");
}
void UpdateMemo(String str)
{
theForm->Memo1->Lines->Add(str);
}
void UpdateStatus(String str)
{
theForm->StatusBar1->SimpleText = str;
}
void Clear()
{
theForm->Memo1->Clear();
}
};
#define mrOK 1
long __fastcall TFormATM::TestConnection()
{ // проверка соединения
try {
CORBA::ORB_ptr orb = CORBA::ORB_init();
Server_ptr S = Server::_bind(ServerNameDlg->ServerNameEdit->Text.c_str());
return S->Balance();
} catch(CORBA::Exception &e) {
return 0;
}
}
//---------------------------------------------------------------------------
void __fastcall TFormATM::FormCreate(TObject *Sender)
{
ATM = new ATMObject();
}
//---------------------------------------------------------------------------
void __fastcall TFormATM::BitBtn1Click(TObject *Sender)
{ // Администрирование
if (ServerNameDlg->ShowModal() == mrOK) {
ATM->serverName(ServerNameDlg->ServerNameEdit->Text);
}
}
//---------------------------------------------------------------------------
void __fastcall TFormATM::BitBtn2Click(TObject *Sender)
{ // Список клиентов
_update * U = new _update(FormATM);
U->UpdateList();
delete U;
}
//---------------------------------------------------------------------------
void __fastcall TFormATM::BitBtn3Click(TObject *Sender)
{ // Выполнение операции
catchit cbuf(Memo1);
ostream CCout(&cbuf); // Visibroker имеет предопределенный Cout
// Создание интерфейса просмотра ATM-объекта
_update* Input = new _update(FormATM);
// Создание объекта транзакции
xaction_var X = new xaction;
// "Заселение" объекта транзакции
X->UserID = Input->UserID();
try {
X->PIN = Input->PIN();
} catch (Exception &e) {
X->PIN = 0;
}
X->amount = Input->Amount();
X->action = Input->ActionType();
X->account = Input->AccountType();
X->balance = 0.00;
X->status = incomplete;
try {
// Старт ORB
CORBA::ORB_ptr orb = CORBA::ORB_init();
Input->UpdateStatus("* ORB Инициализирован.");
// Присоединение к ATM-серверу
Server_ptr ATMServer = Server::_bind(ATM->serverName().c_str());
Input->UpdateStatus("Присоединение к ATM-серверу завершено.");
Input->UpdateStatus("ATM-сервер открыт.");
// Передача транзакции ATM-серверу
ATMServer->HandleTransaction(X);
if (X->status == complete) {
Input->UpdateMemo("Баланс счёта: $" + CurrToStr(X->balance));
Input->UpdateMemo("Транзакция завершена.");
} else if (X->status == incomplete) {
Input->UpdateMemo("Транзакция не обработана.");
Input->UpdateMemo("Баланс счёта: $" + CurrToStr(X->balance));
} else if (X->status == invalid) {
Input->Clear();
Input->UpdateMemo("* ID клиента и PIN не найдены!");
}
}
catch(const CORBA::Exception& e) {
CCout << e._name() << endl;
Input->UpdateStatus("* ATM-сервер отключен!");
}
}
//---------------------------------------------------------------------------
Servername.h
//----------------------------------------------------------------------------
#ifndef servnameH
#define servnameH
//----------------------------------------------------------------------------
#include <vcl\System.hpp>
#include <vcl\Windows.hpp>
#include <vcl\SysUtils.hpp>
#include <vcl\Classes.hpp>
#include <vcl\Graphics.hpp>
#include <vcl\StdCtrls.hpp>
#include <vcl\Forms.hpp>
#include <vcl\Controls.hpp>
#include <vcl\Buttons.hpp>
#include <vcl\ExtCtrls.hpp>
//----------------------------------------------------------------------------
class TServerNameDlg : public TForm
{
__published:
TButton *OKBtn;
TButton *CancelBtn;
TBevel *Bevel1;
TLabel *Label1;
TLabel *ServerNameLabel;
TEdit *ServerNameEdit;
TLabel *Label2;
TButton *ConnectButton;
TLabel *Label3;
TLabel *CountLabel;
TLabel *ResultLabel;
void __fastcall FormShow(TObject/* */ *Sender);
void __fastcall ConnectButtonClick(TObject/* */ *Sender);
void __fastcall OKBtnClick(TObject/* */ *Sender);
private:
public:
virtual __fastcall TServerNameDlg(TComponent* AOwner);
};
//----------------------------------------------------------------------------
extern PACKAGE TServerNameDlg *ServerNameDlg;
//----------------------------------------------------------------------------
#endif
Servername.cpp
#include <vcl.h>
#pragma hdrstop
#include "servname.h"
#include "atmunit.h"
//---------------------------------------------------------------------
#pragma resource "*.dfm"
TServerNameDlg *ServerNameDlg;
//---------------------------------------------------------------------
__fastcall TServerNameDlg::TServerNameDlg(TComponent* AOwner)
: TForm(AOwner)
{
}
//---------------------------------------------------------------------
void __fastcall TServerNameDlg::FormShow(TObject/* */ *Sender)
{
ServerNameLabel->Caption = FormATM->ATM->serverName();
ServerNameEdit->Text = ServerNameLabel->Caption;
ResultLabel->Caption = "";
}
//---------------------------------------------------------------------------
void __fastcall TServerNameDlg::ConnectButtonClick(TObject/* */ *Sender)
{
CountLabel->Caption = String(FormATM->TestConnection());
if (CountLabel->Caption == "0")
ResultLabel->Caption = "* Соединения нет!";
else
ResultLabel->Caption = "Соединение установлено.";
}
//---------------------------------------------------------------------------
void __fastcall TServerNameDlg::OKBtnClick(TObject/* */ *Sender)
{
if (CountLabel->Caption != String("0")) {
FormATM->ATM->serverName(ServerNameEdit->Text);
}
}
//---------------------------------------------------------------------------
Рисунок 5.18. Проект и интерфейс ATM-сервера
#ifndef atmserverunitH
#define atmserverunitH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include "xaction_s.hh"
#include "banking_s.hh"
#include <Buttons.hpp>
//---------------------------------------------------------------------------
class TForm2 : public TForm
{
__published: // IDE-managed Components
TLabel *Transactions;
TEdit *Count;
TEdit *ServerNameEdit;
TLabel *Label1;
TBitBtn *BitBtn1;
TGroupBox *GroupBox2;
TGroupBox *GroupBox1;
TBitBtn *BitBtn2;
TMemo *Memo1;
TComboBox *BankBox;
void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
void __fastcall BitBtn1Click(TObject *Sender);
void __fastcall BitBtn2Click(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TForm2(TComponent* Owner);
void StartServer();
void DownServer();
CORBA::ORB_var orb;
CORBA::BOA_var boa;
CORBA::Object_ptr obj;
String CurrentServerName;
};
//---------------------------------------------------------------------------
extern PACKAGE TForm2 *Form2;
//---------------------------------------------------------------------------
#endif
ATMServerUnit.cpp
#include <vcl.h>
#pragma hdrstop
#include "atmserverunit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2 *Form2;
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
char * const * argV;
int argC;
//---------------------------------------------------------------------------
// /////////////////////////////////////
// Implement CORBA object from skeleton class
// /////////////////////////////////////
class ATMServerImpl : public _sk_Server
{
public:
ATMServerImpl(const char *object_name);
void UpCount(int i = 0){
if (i == 1) {
Form2->Memo1->Lines->Add("ATM-сервер включен.");
return;
}
Form2->Count->Text = String(count++);
}
virtual xaction HandleTransaction(xaction& Transaction)
{
UpCount();
Form2->Memo1->Lines->Add("Банк найден.");
Transaction.status = invalid;
for (int i = 0; i < UserCount; i++) {
if(Transaction.UserID == CardHolders[i]->UserID) {
if (Transaction.PIN == CardHolders[i]->PIN) {
Transaction.status = OK;
try {
BankServer_var BankServer = BankServer::_bind((*Banks[CardHolders[i]->Bank]).c_str());
BankServer->HandleTransaction(Transaction);
Form2->Memo1->Lines->Add("Транзакция с " + *Banks[CardHolders[i]->Bank]);
} catch(CORBA::Exception &e){
Form2->Memo1->Lines->Add("* Сервер банка недоступен!");
return Transaction;
}
}
}
}
// Transaction.status = complete;
return Transaction;
}
virtual CORBA::Long Balance(){UpCount(); return CORBA::Long(count);}
class NoServer: public CORBA::UserException
{
public:
NoServer(){}
static ATMServerImpl::NoServer* _narrow() throw (CORBA::SystemException);
};
private:
int count;
struct _user{
long UserID;
long Bank;
long PIN;
};
_user * CardHolders[10];
long BankOne;
long BankTwo;
int UserCount;
String * Banks[10];
};
ATMServerImpl::ATMServerImpl(const char *object_name=NULL) :
_sk_Server(object_name)
{
count = 0;
UserCount = 0;
UpCount(1);
Banks[0] = new String("BankOne");
Banks[1] = new String("BankTwo");
TStrings *SL = new TStringList();
SL->Add(*Banks[0]);
SL->Add(*Banks[1]);
Form2->BankBox->Items->Assign(SL);
Form2->BankBox->ItemIndex = 0;
BankOne = 0;
BankTwo = 1;
CardHolders[0] = new _user;
CardHolders[1] = new _user;
CardHolders[2] = new _user;
CardHolders[3] = new _user;
CardHolders[4] = new _user;
CardHolders[5] = new _user;
// user 1
CardHolders[0]->UserID = 0; // "John";
CardHolders[0]->PIN = 123;
CardHolders[0]->Bank = BankOne;
UserCount++;
CardHolders[1]->UserID = 1; // "Bill";
CardHolders[1]->PIN = 456;
CardHolders[1]->Bank = BankOne;
UserCount++;
CardHolders[2]->UserID = 2; // "Jim";
CardHolders[2]->PIN = 789;
CardHolders[2]->Bank = BankOne;
UserCount++;
CardHolders[3]->UserID = 3; // "John";
CardHolders[3]->PIN = 123;
CardHolders[3]->Bank = BankTwo;
UserCount++;
CardHolders[4]->UserID = 4; // "Bill";
CardHolders[4]->PIN = 456;
CardHolders[4]->Bank = BankTwo;
UserCount++;
CardHolders[5]->UserID = 5; // "Jim";
CardHolders[5]->PIN = 789;
CardHolders[5]->Bank = BankTwo;
UserCount++;
}
ATMServerImpl* ATMServer;
void TForm2::StartServer()
{
try {
// Инициализация ORB и BOA
orb = CORBA::ORB_init(argC, argV);
boa = orb->BOA_init(argC, argV);
if (obj) {
Form2->Memo1->Lines->Add("* ATM-сервер уже активен!");
ServerNameEdit->Text = CurrentServerName;
} else {
// Создание нового серверного объекта
obj = new ATMServerImpl(ServerNameEdit->Text.c_str()); //"Wells Fargo");
CurrentServerName = ServerNameEdit->Text;
// Экспорт созданного объекта
boa->obj_is_ready(obj);
// Ожидание приходящих запросов
// boa->impl_is_ready();
}
} catch(const CORBA::Exception& e) {
ShowMessage("* Перехвачено CORBA-исключение!");
}
}
void TForm2::DownServer()
{
try {
if (obj) {
boa->deactivate_obj(obj);
obj->_release();
obj = obj->_nil();
}
Form2->Memo1->Lines->Add("* ATM-сервер отключен!");
} catch(CORBA::Exception &e){
ShowMessage("* Проблема при отключении ATM-сервера!");
}
}
//---------------------------------------------------------------------------
class ServerThread : public TThread
{
public:
__fastcall ServerThread(bool CS):TThread(CS){};
void __fastcall Execute()
{
try {
// Инициализвция ORB и BOA
CORBA::ORB_var orb = CORBA::ORB_init(argC, argV);
CORBA::BOA_var boa = orb->BOA_init(argC, argV);
// Создание нового серверного объекта
ATMServerImpl ATMServer("Wells Fargo");
// Экспорт созданного объекта
boa->obj_is_ready(&ATMServer);
// Ожидание приходящих запросов
boa->impl_is_ready();
} catch(const CORBA::Exception& e) {
ShowMessage("* Перехвачено CORBA-исключение!");
}
}
};
ServerThread * ST;
//---------------------------------------------------------------------------
void __fastcall TForm2::FormClose(TObject *Sender, TCloseAction &Action)
{ // отключение сервера
BitBtn1->Caption = "Включение AYM-сервера";
DownServer();
}
//---------------------------------------------------------------------------
void __fastcall TForm2::BitBtn1Click(TObject *Sender)
{ // включение/отключение ATM-сервера
static bool ServerStarted = false;
if (!ServerStarted) { // включение сервера
Form2->Height = 237;
BitBtn1->Caption = "Отключение ATM-сервера";
// ST = new ServerThread(false);
StartServer();
} else { // отключение сервера
Form2->Height = 108;
BitBtn1->Caption = "Включение ATM-сервера";
DownServer();
}
ServerStarted = !ServerStarted;
}
//---------------------------------------------------------------------------
void __fastcall TForm2::BitBtn2Click(TObject *Sender)
{ // подключение к серверу выбранного в списке банка
try { // попытка подключения к серверу выбранного в списке банка
BankServer_ptr BankServer =
BankServer::_bind(Form2->BankBox->Items->Strings[BankBox->ItemIndex].c_str());
// занесение ID банка в Memo
long ID = BankServer->BankID();
Form2->Memo1->Lines->Add(
AnsiString ("Банк ") +
(ID == 800 ? AnsiString("BankTwo") : AnsiString("BankOne")) +
AnsiString(" подключен."));
} catch(CORBA::Exception &e){
ShowMessage(e._name());
}
}
Рисунок 5.19. Проект и интерфейс BankServerOne
#ifndef BankUnitOneH
#define BankUnitOneH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Buttons.hpp>
#include <ComCtrls.hpp>
//---------------------------------------------------------------------------
class TBankOneForm : public TForm
{
__published: // IDE-managed Components
TEdit *CountBox;
TLabel *Label1;
TMemo *Memo1;
TBitBtn *BitBtn1;
TStatusBar *StatusBar1;
void __fastcall BitBtn1Click(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TBankOneForm(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TBankOneForm *BankOneForm;
//---------------------------------------------------------------------------
#endif
BankUnitOne.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "BankUnitOne.h"
#include "banking_s.hh"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
AnsiString Accounts [] = {"Проверка", "Кредит"};
AnsiString Operations [] = {"Баланс", "Снять", "Внести"};
TBankOneForm *BankOneForm;
//---------------------------------------------------------------------------
__fastcall TBankOneForm::TBankOneForm(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
char * const * argV;
int argC;
//---------------------------------------------------------------------------
// ///////////////////////////////////////////
// Implement CORBA object from skeleton class
// ///////////////////////////////////////////
class BankServerImpl : public _sk_BankServer
{
public:
BankServerImpl(const char *object_name);
void UpCount(int i = 0) {
if (i == 1) {
BankOneForm->StatusBar1->SimpleText = "Сервер включен";
return;
}
BankOneForm->CountBox->Text = String(++count);
}
virtual long BankID()
{
return BankNumber;
}
virtual xaction HandleTransaction(xaction& Transaction)
{
bool PostChange = false;
double workingBalance = 0;
UpCount();
Transaction.status = incomplete;
BankOneForm->Memo1->Lines->Add("ID клиента: " + String(Transaction.UserID));
BankOneForm->Memo1->Lines->Add("Счет: " + Accounts[Transaction.account]);
BankOneForm->Memo1->Lines->Add("Операция: " + Operations[Transaction.action]);
for (int i = 0; i < UserCount; i++) {
if (Transaction.UserID == Customers[i]->UserID) {
if (Transaction.account == 1)
workingBalance = Customers[i]->AccountChecking;
else
workingBalance = Customers[i]->AccountSavings;
switch (Transaction.action) {
case balance:
Transaction.balance = workingBalance;
Transaction.status = complete;
break;
case withdraw:
Transaction.balance = workingBalance;
workingBalance -= Transaction.amount;
if (workingBalance < 0) {
Transaction.status = incomplete;
} else {
Transaction.balance = workingBalance;
Transaction.status = complete;
PostChange = true;
}
break;
case deposit:
workingBalance += Transaction.amount;
Transaction.balance = workingBalance;
Transaction.status = complete;
PostChange = true;
break;
}
if (PostChange) {
if (Transaction.account == 1)
Customers[i]->AccountChecking = workingBalance;
else
Customers[i]->AccountSavings = workingBalance;
}
}
}
return Transaction;
}
private:
long BankNumber;
int count;
int UserCount;
struct _user{
long UserID;
double AccountChecking;
double AccountSavings;
};
_user * Customers[10];
};
BankServerImpl::BankServerImpl(const char *object_name = NULL):
_sk_BankServer(object_name)
{
BankNumber = 900;
count = 0;
UserCount = 0;
Customers[0] = new _user;
Customers[1] = new _user;
Customers[2] = new _user;
Customers[0]->UserID = 0; // "John"
Customers[0]->AccountChecking = 2000.00;
Customers[0]->AccountSavings = 90.00;
UserCount++;
Customers[1]->UserID = 1; // Bill;
Customers[1]->AccountChecking = 100.00;
Customers[1]->AccountSavings = 500.00;
UserCount++;
Customers[2]->UserID = 2; // Jim;
Customers[2]->AccountChecking = 1000.00;
Customers[2]->AccountSavings = 5000.00;
UserCount++;
}
//---------------------------------------------------------------------------
class ServerThread : public TThread
{
public:
__fastcall ServerThread(bool CS):TThread(CS){};
void __fastcall Execute()
{
try {
// Инициализация ОRB и BOA
CORBA::ORB_var orb = CORBA::ORB_init(argC, argV);
CORBA::BOA_var boa = orb->BOA_init(argC, argV);
// Создание нового серверного объекта
BankServerImpl BankServer("BankOne");
// Экспорт сервероного объекта
boa->obj_is_ready(&BankServer);
BankOneForm->StatusBar1->SimpleText = "Сервер включен";
// Ожидание приходящих запросов
boa->impl_is_ready();
} catch(const CORBA::Exception& e) {
ShowMessage("* Перехвачено CORBA-исключение!");
}
}
};
ServerThread * ST;
//---------------------------------------------------------------------------
void __fastcall TBankOneForm::BitBtn1Click(TObject *Sender)
{ static bool Switch = false;
Switch = !Switch;
BitBtn1->Caption = "Отключение сервера банка";
if (Switch) ST = new ServerThread(false);
else Close();
}
Подобные документы
Разработка системы, базирующейся на протоколе LIMone, для обмена мгновенными сообщениями и пересылки файлов в процессе деловой переписки. Реализация системы в виде клиент-серверного приложения. Расчет экономических показателей программного продукта.
дипломная работа [4,7 M], добавлен 22.08.2016Сетевое программное обеспечение: общее понятие, содержание, функции. Этапы развития теории компьютерных сетей. Проектирование в среде программирования Borland Builder C++ клиент серверного приложения с использованием сокетов, листинг данной программы.
курсовая работа [191,5 K], добавлен 07.01.2015Изучение истории достижений корпорации Oracle. Разработка клиент-серверного приложения на языке Delphi XE, реализующего возможность управления персоналом на предприятии. Основные структуры данных. Создание инструкции работы с приложением "Отдел кадров".
дипломная работа [974,7 K], добавлен 08.06.2013Технология CORBA (Общая Архитектура Брокера Объектных запросов): интерфейс, управление объектами. Создание сервисного приложения, простейшего объекта. Установка связи между клиентом и серверным объектом. Массивы, обработка ошибок и устойчивость к сбоям.
реферат [37,3 K], добавлен 09.11.2011Технология распределенных вычислений CORBA, взаимодействие компонентов и архитектура. Основное назначение CORBA и COM. Поддержка операционных систем, предлагаемые службы и масштабируемость. Формальное описание архитектуры и проблемы ее реализации.
курсовая работа [89,3 K], добавлен 02.12.2013Разработка клиент-серверного приложения, позволяющего взаимодействовать друг с другом с использованием доступа к базам данных. Проектирование связи сервера с базой данных с помощью технологии ODBC. Разработка интерфейса программы, ее тестирование.
курсовая работа [352,0 K], добавлен 24.08.2016Многоуровневые архитектуры клиент–сервер. Диаграммы классов, реализующих уровни презентации, бизнес–логики и базы данных приложения. Словесное описание процесса выполнения транзакций. Создание, изменение и удаление хранимых процедур, их выполнение.
курсовая работа [3,4 M], добавлен 23.03.2013Проектирование физической и логической моделей удаленной базы данных для АЗС. Разработка базы данных в СУБД Firebird с помощью утилиты IBExpert. Создание клиентского приложения для Windows с использованием клиент-серверной технологии в среде C++ Builder.
курсовая работа [3,9 M], добавлен 18.01.2017Объект CORBA и жизненный цикл серванта. Общий протокол межброкерного взаимодействия (GIOP). Связывание с языком высокого уровня. Статические и динамические вызовы. Применение технологии CORBA при построении распределенных информационных приложений.
курсовая работа [407,4 K], добавлен 23.12.2014Основные понятия серверов. Модель клиент-сервер. Классификация стандартных серверов. Недостатки файл-серверной системы. Криптографические методы защиты информации. Серверы удаленного доступа. Методы и средства обеспечения безопасности информации.
контрольная работа [36,3 K], добавлен 13.12.2010