Tài liệu Mô hình Client - Server: ... Ebook Mô hình Client - Server
37 trang |
Chia sẻ: huyen82 | Lượt xem: 1545 | Lượt tải: 0
Tóm tắt tài liệu Mô hình Client - Server, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
Lêi nãi ®Çu
Ngµy nay cïng víi viÖc ph¸t triÓn cña m¹ng m¸y tÝnh viÖc viÕt mét øng dông trªn mét m¸y ®¬n côc bé kh«ng cßn ®îc a chuéng vµ thÝch hîp n÷a . C¸c ch¬ng tr×nh vµ øng dông hiÖn ®¹i ph¶i tÝch hîp vµ triÖu gäi lÉn nhau trªn m¹ng Intranet (m¹ng côc bé), m¹ng Internet (m¹ng toµn cÇu).
Tuy nhiªn mét vÊn ®Ò n¶y sinh ra , ®iÓm bÊt ®ång gi÷a c¸c ng«n ng÷ lËp tr×nh . C¸c ®èi tîng thiÕt kÕ b»ng ng«n ng÷ nµo th× sau khi biªn dÞch ra d¹ng nhÞ ph©n (binary) chØ cã m· lÖnh t¬ng øng víi ng«n ng÷ ®ã míi cã kh¶ n¨ng truy xuÊt ®îc ®èi tîng . §èi tîng C++ kh«ng dÔ g× truy xuÊt ®îc tõ m· lÖnh Delphi hay Visual Basic mét c¸ch tù nhiªn . (MÆc dï cã mét sè kÜ thuËt nh sö dông th viÖn liªn kÕt ®éng DLL nhng ®ã kh«ng ph¶i lµ c¸c gi¶i ph¸p toµn diÖn ).
C¸c nhµ lËp tr×nh lu«n mong muèn t×m ®îc mét tiÕng nãi chung cho tÊt c¶ c¸c ng«n ng÷ lËp tr×nh hiÖn cã . Vµ thÕ lµ CORBA ra ®êi .
CORBA ( Common Object Request Broker Achitecture) - t¹m dÞch lµ KiÕn tróc m«i giíi gäi c¸c ®èi tîng th«ng dông . CORBA ®îc h×nh thµnh tõ mét tæ chøc nghiªn cøu quèc tÕ OMG (Object Management Group ) víi sù hîp t¸c cña h¬n 800 c«ng ty . Tham väng cña OMG lµ ®a ra c¸ch ®Ó c¸c ®èi tîng viÕt b»ng nh÷ng ng«n ng÷ kh¸c nhau cã thÓ triÖu gäi lÉn nhau theo m« h×nh ®èi tîng ph©n t¸n .
CORBA kh«ng ph¶i lµ ng«n ng÷ lËp tr×nh nh C++ hay Java . CORBA lµ mét ng«n ng÷ ®Æc t¶ (description language) .
Sau ®©y sÏ tr×nh bµy qu¸ tr×nh ¸nh x¹ (mapping) tõ ng«n ng÷ ®Æc t¶ sang ng«n ng÷ cµi ®Æt
I. ¸nh x¹ tõ IDL sang C++
Giíi thiÖu:
¸nh x¹ IDL sang C++ ph¶i tho· m·n c¸c yªu cÇu sau : - ¸nh x¹ ph¶i cã tÝnh trùc quan vµ dÔ sö dông
ph¶i b¶o tån ng«n ng÷ chung cña C++ vµ ph¶i gÇn gièng víi C++ thêng
ph¶i an toµn vÒ kiÓu
sö dông cã hiÖu qu¶ chu kú cña CPU vµ bé nhí
thùc hiÖn trªn c¸c cÊu tróc cña bé nhí ®o¹n vµ bé nhí vËt lý
ph¶i ®îc híng néi sao cho nã cã thÓ dïng trong m«i trêng ph©n luång
¸nh x¹ ph¶i b¶o toµn tÝnh che giÊu côc bé (tÝnh trong suèt)
ViÖc ¸nh x¹ sang C++ phøc t¹p vµ réng lín nhng kh«ng ph¶i qu¸ khã. Thø nhÊt, ¸nh x¹ lµ thuËn tiÖn vÝ dô b¹n hiÓu râ vÒ c¸ch tæ chøc vµ qu¶n lý bé nhí cña kiÓu String, vµ c¸c luËt qu¶n lý ®èi víi kiÓu d÷ liÖu Variable-length, thø hai, viÖc ¸nh x¹ lµ an toµn, kh«ng yªu cÇu s¾c th¸i vµ b¾t lçi dÔ dµng trong lóc biªn dÞch
Thø 3, sù ¸nh x¹ nµy lµ dÔ nhí mÆc dï líp cã nhiÒu hµm thµnh viªn, nhng b¹n chØ cÇn gäi mét sè hµm chÝnh, cßn mét sè hµm kh¸c tån t¹i mÆc ®Þnh ®Ó cung cÊp c¸c chuyÓn ®æi tham sè truyÒn vµ kh«ng cÇn ph¶i gäi râ rµng
2. ¸nh x¹ cho tªn:
Các tên của IDL được bảo toàn khi ánh xạ sang C++. Để minh hoạ cho điều này ta xét ví dụ sau:
Trong IDL:
enum color {red, green, blue};
Khi ánh xạ sang C++:
enum color {red, green, blue};
Các ánh xạ sang C++ cũng bảo toàn các toán tử phạm vi. Ví dụ nếu như trong IDL toán tử phạm vi Outer :: Inner là hợp lệ thì khi ánh xạ sang C++ nó cũng vẫn là Outer :: Inner.
Một vấn đề phát sinh khi trong IDL ta dùng tên trùng với từ khoá trùng với các từ khoá của C++:
Ví dụ định nghĩa sau là hoàn toàn hợp lệ trong IDL:
Enum class {if, this, while, case };
nhưng khi ánh xạ sang C++ thì nó sẽ tự động được thêm vào tiền tố: _cxx_. Vì vậy nó sẽ có dạng như sau:
enum _cxx_class { _cxx_if, _cxx_this, _cxx_while, _cxx_case };
các tiền tố này làm cho các câu lệnh trở nên khó đọc, do vậy tốt nhất là ta nên tránh dùng chúng.
Bây giờ chúng ta sẽ đi xét chi tiết vào từng kiểu dữ liệu một
3. Ánh xạ các kiểu dữ liệu cơ bản
Các kiểu dữ liệu cơ bản được ánh xạ sang C++ được mô tả ở bảng sau:
OMG IDL
C++
C++ Out Type
short
CORBA::Short
CORBA::Short_out
long
CORBA::Long
CORBA::Long_out
unsigned short
CORBA::UShort
CORBA::UShort_out
unsigned long
CORBA::ULong
CORBA::ULong_out
float
CORBA::Float
CORBA::Float_out
double
CORBA::Double
CORBA::Double_out
char
CORBA::Char
CORBA::Char_out
boolean
CORBA::Boolean
CORBA::Boolean_out
octet
CORBA::Octet
CORBA::Octet_out
4. Các kiểu dữ liệu phức:
Các kiểu dữ liệu phức ở trong IDL được ánh xạ sang C++ như sau:
OMG IDL
C++
Object
CORBA::Object_ptr
struct
C++ struct
union
C++ class
enum
C++ enum
string
char *
Sequence
C++ class
array
C++ array
a>. String
Một chuỗi trong IDL được ánh xạ sang C++ là char *. Cả chuỗi giới hạn và chuỗi không giới hạn độ dài thì đều được ánh xạ sang C++ là char *. Các chuỗi CORBA trong C++ được kết thúc bởi con trỏ NULL. Nếu một chuỗi mà có chứa một kiểu tự định nghĩa khác, ví dụ như kiểu struct, thì nó được ánh xạ sang kiểu C ORBA::String_v ar. Điều này đảm bảo rằng mỗi thành phần trong struct được quản lý bởi chính bộ nhớ của nó. Các chuỗi phải được cấp phát và ngừng cấp phát bằng việc sử dụng các hàm thành phần sau trong lớp CORBA:
string_alloc // hàm cấp phát
string_dup
string_free // hàm huỷ
Chú ý: hàm string_alloc cấp phát vùng nhớ có độ dài len+1 vì nó còn chứa một ký tự null
b>.Enum
Các kiểu enum trong IDL được ánh xạ sang một kiểu enum trong C++
// IDL
module INVENT { enum Reply {ACCEPT, REFUSE}; }
// C++
class INVENT { . . .
enum Reply {ACCEPT, REFUSE}; };
Tham chiếu đến các thành phần như sau là hợp lệ:
INVENT::Reply accept_reply; accept_reply = INVENT::ACCEPT;
c> .Struct
Các kiểu struct trong IDL được ánh xạ sang các kiểu struct trong C++. Chúng ta cùng xem xét các cấu trúc có chiều dài cố định với các cấu trúc có chiều dài thay đổi:
// IDL
module INVENT { // Chiều dài cố định struct Date { long year; long month; long day; }; // Chiều dài thay đổi struct Address { string aptNum; string streetName; string city; string state; string zipCode; }; };
// C++
class INVENT { struct Date { CORBA::Long year; CORBA::Long month; CORBA::Long day; };
struct Address { CORBA::String_var aptNum; CORBA::String_var streetName; CORBA::String_var city; CORBA::String_var state; CORBA::String_var zipCode; Address &operator=(const Address &_obj); }; };
Đối với các kiểu dữ liệu cơ bản trong các thành phần của struct được ánh xạ sang các kiểu tương ứng trong C++. Còn các kiểu dữ liệu như: tham chiếu đối tượng, các tham chiếu giả đối tượng, các chuối thì được ánh xạ các lớp _var tương ứng:
CORBA::string_var
CORBA::object_var
Union
Một kiểu Union trong IDL được ánh xạ sang một lớp trong C++. Lớp này chứa:
Các hàm tạo lập (Constructors)
Các hàm huỷ (Destructors)
Các toán tử gán
Các thay đổi cho các giá trị của union
Các bộ truy nhập cho các giá trị của union.
Ví dụ:
// IDL
union OrderItem switch (long) { case 1: itemStruct itemInfo; case 2: orderStruct orderInfo; default: ID idInfo; };
// C++
class OrderItem { public: OrderItem(); OrderItem(const OrderItem &); ~OrderItem(); OrderItem &operator=(const OrderItem&);
void _d (CORBA::Long); CORBA::Long _d () const; void itemInfo (const itemStruct &); const itemStruct & itemInfo () const; itemStruct & itemInfo (); void orderInfo (const orderStruct &); const orderStruct & orderInfo () const; orderStruct & orderInfo (); void idInfo (ID); ID idInfo () const; . . . };
Các định nghĩa kiểu
Các định nghĩa kiểu trong IDL được ánh xạ trực tiếp sang các định nghĩa kiểu của C++. Nếu định nghĩa kiểu IDL gốc được ánh xạ sang một vài kiểu của C++ thì trình biên dịch của IDL sẽ sinh ra các bí danh tương ứng cho mỗi kiểu trong C++.
// IDLtypedef octet example_octet;typedef enum enum_values { first, second, third} enum_example;
// Kết quả trong C++
typedef octet example_octet;enum enum_values { first, second, third};
typedef enum_values enum_example; // bí danh được tạo ra
Modules
Một module của IDL nên được ánh xạ sang một namespace của C++ với tên tương tự
// IDLmodule ABC{ // Definitions ...};...// Kết quả trong C++class ABC{ // Definitions ...};
Sequences
Các sequences của IDL cả giưói hạn hay không giới hạn đều được ánh xạ sang class của C++.
Chú ý: Khi chiều dài của sequence không giới hạn vượt quá chiều dài cực đại thì C++ sẽ cấp phát trong suốt một buffer lớn hơn, nó sẽ copy buffer cũ vào buffer mới và giải phong bộ nhớ khỏi buffer cũ. Tuy nhiên, nó sẽ không thực hiện giải phóng bất kỳ bộ nhớ nào chưa bao giờ được dùng đến nếu chiều dài cực đại giảm.
Xét ví dụ sau: ánh xạ một sequence không giới hạn (unbounded)của IDL sang C++
// IDLtypedef sequence LongSeq;...// Results in the generation of this C++ codeclass LongSeq{public: LongSeq(CORBA::ULong max=0); LongSeq(CORBA::ULong max=0, CORBA::ULong length, CORBA::Long *data, CORBA::Boolean release = 0); LongSeq(const LongSeq&); ~LongSeq(); LongSeq& operator=(const LongSeq&); CORBA::ULong maximum() const; void length(CORBA::ULong len); CORBA::ULong length() const; const CORBA::ULong& operator[](CORBA::ULong index) const; ... static LongSeq *_duplicate(LongSeq* ptr); static void _release(LongSeq *ptr); static CORBA::Long *allocbuf(CORBA::ULong nelems); static void freebuf(CORBA::Long *data);private: CORBA::Long *_contents; CORBA::ULong _count; CORBA::ULong _num_allocated: CORBA::Boolean _release_flag; CORBA::Long _ref_count;};
Ý nghĩa của các hàm được môt tả ở bảng sau:
Phương thức
Mô tả
LongSeq(CORBA::ULong max=0)
bộ tạo lập cho một sequence không giới hạn chiếm một chiều dài cực đại như một tham số. Các sequence giới hạn thì có một chiều dài cực đại xác định.
LongSeq(CORBA::ULong max=0, CORBA::ULong length, CORBA::Long *data, CORBA::Boolean release=0)
Constructor này cho phép bạn đặt một chiều dài cực đại, chiều dài hiện tại, một con trỏ tới bộ đệm dữ liệu kết hợp và một cờ giải phóng.Nếu cờ giải phóng khác 0, ISB về C++ sẽ giải bộ nhớ kết hợp với bộ đẹm dữ liệu khi tăng kích thước của sequence. Nếu cờ giải phóng bằng 0 thì bộ nhớ của bộ dệm dữ liệu cũ không được giải phóng. Sequence giới hạn có tất cả các thông số này trừ max.
LongSeq(const LongSeq&)
Bộ tạo lập sao chép thực hiện sao chép sâu đối tượng nguồn.
~LongSeq();
Destructor giải phóng tất cả bộ nhớ của chính sequence nếu cờ giải phóng (release flag) có giá trị khác không khi được tạo lập.
Operator=(const LongSeq&j)
Toán tử gán thực hiện một sự ao chép sâu, giải phóng việc lưu trữ cũ nếu cần thiết..
Maximum()
Trả lại kích thước của sequence.
length()
Hai phương thức được định nghĩa cho việc đặt và trả lại chiều dài của sequence.
Operator[]()
Hai toán tử chỉ mục được cung cấp cho việc truy nhập một phần tử trong sequence. Một toán tử cho phép phần tử được thay đổi còn một toán tử chỉ cho phép truy nhập đọc phần tử.
_release()
Giải phóng sequence. Nếu cờ giải phóng của bộ tạo lập là khác 0 khi đối tượng được khởi tạo và kiểu phần tử của sequence là một chuỗi hoặc tham chiếu đối tượng thì mỗi phần tử sẽ được giải phóng trước khi buffer được giải phóng.
allocbuf() freebuf()
Bạn nên dùng hai phương thức tĩnh này để cấp phát hay huỷ bất kỳ bộ nhớ nào sử dụng bởi một sequence
Quản lý bộ nhớ về các sequence
Bạn nên cân nhắc cẩn thận các vấn đề quản lý bộ nhớ được chỉ ra dưới đây:
Nếu cờ giải phống được đặt giá trị khác 0 khi sequence được khởi tạo, thì sequence sẽ giả định quản lý bộ nhớ của người dùng. Khi một phần tử được gán, bộ nhớ cũ được giải phóng trước khi quyền sở hữu của bộ nhớ của biểu thức bên tay phải được thừa nhận.
Nếu cờ giải phóng được đặt giá trị khác 0 khi sequence được khởi tạo và các phần tử của sequence là các chuỗi hay các tham chiếu đối tượng, mỗi phần tử sẽ được giải phóng trước khi buffer chứa nội dung của sequence được giải phóng và đối tượng bị huỷ.
Tránh việc gán một phần tử của sequence sử dụng toán tử [] trừ khi cờ giải phóng được đặt là 1, hoặc lỗi quản lý bộ nhớ xuất hiện.
Các sequence được khởi tạo với cờ huỷ đặt bằng 0 không nên được sử dụng như các tham biến đầu vào/ đầu ra bởi vì các lỗi quản lý bộ nhớ trong bộ dịch vụ đối tượng có thể đưa đến kết quả.
Luôn luôn sử dụng allocbuf và freebuf để khởi tạo và giải phóng kho lưu trữ được sử dụng với các sequence.
Array
Các array của IDL được ánh xạ sang các array của C++, cái mà có thể được khởi tạo tĩnh. Nếu các phần tử của array là các chuỗi hoặc các tham chiếu đối tượng, thì các phần tử của mảng trong C++ có kiểu _var. Ví dụ đoạn chương trình sau chỉ ra ba mảng với các kiểu phần tử khác nhau.
// IDLinterface Intf{ // definitions...};typedef long L[10];typedef string S[10];typedef Intf A[10]; // kiểu tham chiếu đối tượng...// Kết quả trong C++typedef CORBA::Long L[10];typedef CORBA::String_var S[10];typedef Intf_var A[10];
Cách sử dụng kiểu được quản lý kiểu _var cho các chuỗi và các tham chiếu đối tượng cho phép bộ nhớ được quản lý trong suốt khi các phần tử của mảng được gán.
Các slice của mảng
Kiểu _slice của mảng được sử dụng khi truyền tham số cho các mảng nhiều chiều. Một slice của một mảng với tất cả các chiều của mảng gốc trừ chiều đầu tiên. Kiểu mảng _slice cung cấp một cách thuận lợi cho việc truyền và trả lại các tham số. Một định ngh ĩa ki ểu cho m ỗi slice được phát sinh.
// IDLtypedef long L[10];typedef string str[1][2][3];...// Results in the generation of these slicestypedef CORBA::Long L_slice[10];typedef CORBA::String_var str_slice[2][3];typedef str_slice *str_slice_ptr;
Nếu bạn chỉ có mảng một chiều, một mảng slice chỉ là một kiểu. Như bạn thấy ở ví dụ trên, ta có mảng long L[10] thì một mảng slice sẽ trả lại kết quả trong kiểu dữ liệu là CORBA::Long
Quản lý bộ nhớ cho các mảng
Trình biên dịch IDL của C++ sinh ra hai hàm phục vụ cho việc cấp phát và giải phóng bộ nhớ kết hợp với các mảng. Các hàm này cho phép ORB quản lý bộ nhớ mà không ghi đè các toán tử new và delete.
// IDLtypedef long L[10];...
// Kết quả trong C++inline L_slice *L_alloc(); // Cấp phát động một mảng. Trả lại giá trị NULL nếu lỗi.
inline void L_free(L_slice *data); // Giải phóng bộ nhớ mảng được cấp phát bởi L_loc.
* Quản lý các ngoại lệ (Exception)
Một exception trong Idl được ánh xạ sang một lớp của C++. Lớp này chứa các thành phần sau:
Các bộ tạo lập (constructor)
Destructors
Một hàm _narrow static để xác định kiểu của exception.
// OMG IDL
module INVENT { exception NonExist { ID BadId; }; };
// C++
class INVENT { . . .
class NonExist : public CORBA::UserException { public: static NonExist * _narrow(CORBA::Exception_ptr); NonExist (ID _BadId); NonExist (); NonExist (const NonExist &); ~NonExist (); NonExist & operator=(const NonExist &); void _raise (); ID BadId; }; };
Các thuộc tính của lớp Exception là public vì vậy bạn có thể truy nhập trực tiếp.
Ánh xạ các các bộ phận
Các bộ phận của lớp ngoại lệ được ánh xạ theo cách tương tự như các cấu trúc. Tất cả các bộ phận của ngoại lệ là dữ liệu công cộng trong lớp của C++, và được truy nhập trực tiếp.
Var
Một lớp _var được sinh ra cho một ngoại lệ.
Out
Một lớp Out được sinh ra cho một ngoại lệ.
Các hàm bộ phận
Với ngoại lệ của IDL là TYPE có các hàm bộ phận sau:
static TYPE * _narrow(CORBA::Exception_ptr Except);
TYPE(); Đây là constructor mặc định cho ngoại lệ
TYPE(các tham chiếu bộ phận);
TYPE (const TYPE & From);
~TYPE ();
TYPE & operator=(const TYPE & From);
void _raise ();
* Quản lý các giao diện (interface)
Một giao diện trong IDL được ánh xạ sang một lớp của C++. Lớp này chứa các định nghĩa của các thao tác, các thuộc tính, các hằng, và các kiểu người dùng định nghĩa (UDTs).
Với một giao diện INTF, đoạn mã giao diện được sinh ra chứa các phần sau:
Kiểu tham chiếu đối tượng (INTF_ptr)
Kiểu biến tham chiếu đối tượng (INTF_var)
Hàm bộ phận tĩnh _duplicate
Hàm bộ phận tĩnh _narrow
Hàm bộ phận tĩnh _nil
UDTs
Các hàm bộ phận về các thuộc tính và các thao tác
Xét ví dụ sau:
// OMG IDL
module INVENT { interface Order { void cancelOrder (); }; };
Ánh xạ sang C++ như sau:
// C++ class INVENT { . . . class Order; typedef Order * Order_ptr;
class Order : public virtual CORBA::Object { . . . static Order_ptr _duplicate(Order_ptr obj); static Order_ptr _narrow(CORBA::Object_ptr obj); static Order_ptr _nil(); virtual void cancelOrder () = 0; . . . }; };
Các kiểu tham chiếu đối tượng và các hàm bộ phận được mô tả như sau:
static INTF_ptr _duplicate (INTF_ptr Obj)
Hàm bộ phận tĩnh này sao chép một tham chiếu đối tượng INTF đang tồn tại và trả lại một tham chiếu đối tượng INTF mới. Tham chiếu đối tượng INTF mới phải được giải phóng bằng việc gọi hamf bộ phận CORBA::realease. Nếu một lỗi xuất hiện thì một tham chiếu tới đối tượng INTF nil được trả lại. Đối số Obj xác định tham chiếu đối tượng được sao chép.
static INTF_ptr _narrow (CORBA::Object_ptr Obj)
Hàm bộ phận tĩnh này trả lại một tham chiếu đối tượng INTF mới dựa vào một tham chiếu đối tượng CORBA::Object_ptr đang tồn tại. Tham chiếu đối tượng Obiect_ptr có thể được khởi tạo bằng việc gọi hàm bộ phận CORBA::ORB::string_to_object hoặc có thể được trả lại như một tham chiếu từ một thao tác.
Tham chiếu đối tượng INTF_ptr phải tương ứng với một đối tượng INTF hoặc tương ứng với một đối tượng mà kế thừa từ đối tượng INTF. Tham chiếu đối tượng INTF mới phải được giải phóng bằng việc gọi hàm bộ phận CORBA::release. Đối số Obj xác định tham chiếu đối tượng để thu hẹp tới một tham chiếu đối tượng INTF. Tham biến Obj không bị thay đổi bởi các hàm bộ phận này và nên đựoc giải phóng bởi người sử dụng khi nó không được sử dụng nữa. Nếu Obj không được thu hẹp tới một tham chiếu đối tượng INTF thì một tham chiếu đối tượng INTF nil được trả lại.
static INTF_ptr _nil ( )
Hàm bộ phận static này trả lại một tham chiếu đối tượng nil mới cho giao diện INTF. Tham chiếu mới không phải được giải phóng bằng cách gọi hàm bộ phận CORBA::release.
Các kiểu tham chiếu đối tượng
Một lớp giao diện (INTF) là một lớp ảo; CORBA chuẩn không cho phép bạn:
Khởi tạo hay hold một instance của lớp giao diện.
Sử dụng một con trỏ hay một tham chiếu tới một lớp giao diện.
Thay vì đó bạn có thể sử dụng một kiểu tham chiếu đối tượng: lớp INTF_ptr hay INTF_var.
Bạn có thể giành được tham chiếu đối tượng bằng việc sử dụng hàm bộ phận static _nrrow. Các thao tác truy nhập trên các lớp này thì sử dụng toán tử ->
Lớp _var của INTF đơn giản hoá việc quản lý bộ nhớ bằng việc huỷ tự động tham chiếu đối tượng khi lớp _var của INTF nằm ngoài phạm vi được cấp phát lại.
Các thuộc tính
Một thuộc tính chỉ đọc trong OMG IDL được ánh xạ sang một hàm C++ mà hàm đó trả lại giá trị thuộc tính. Một thuộc tính đọc-ghi ánh xạ sang hai hàm C++ được chòng hàm, một hàm trả lại giá trị thuộc tính và một hàm trả lại tập giá trị thuộc tính. Tên của hàm bộ phận được chồng hàm là tên của thuộc tính. Các thuộc tính được tạo ra theo cách tương tự mà các hàm được tạo ra.
II. ¸nh x¹ phÝa server
Trong phÇn nµy chóng ta sÏ xem c¸ch mµ c¸c giao tiÕp IDL ¸nh x¹ sang c¸c líp C++ cïng víi sù hç trî viÖc t¹o vµ gäi ®èi tîng CORBA ë bªn phÝa server vµ mét sè vÊn ®Ò liªn quan kh¸c .
1 . Më ®Çu :
Trong m« h×nh CORBA c¸c ®èi tîng server thùc hiÖn bëi øng dông server.T¹i server, ®èi tîng CORBA ®îc thùc thi vµ thÓ hÞªn bëi c¸c hµm ng«n ng÷ lËp tr×nh vµ d÷ liÖu. C¸c thùc thÓ ng«n ng÷ lËp tr×nh thùc thi vµ thÓ hiÖn c¸c ®èi tîng CORBA ®îc gäi lµ c¸c servant.
C¸c servant cung cÊp c¸c phÇn th©n cña ®èi tîng CORBA, hay nãi c¸ch kh¸c chóng lµ thÓ hiÖn cña c¸c ®èi tîng CORBA.
Trong CORBA c¸c bé ®iÒu hîp ®èi tîng(object adapter ) liªn kÕt c¸c ®èi tîng CORBA víi c¸c servant cña ng«n ng÷ lËp tr×nh. VÒ kh¸i niÖm th× bé ®iÒu hîp ®èi tîng lµm trung gian gi÷a ORB vµ c¸c servant cña ng«n ng÷ lËp tr×nh. Chóng cung cÊp c¸c dÞch vô ®Ó t¹o c¸c ®èi tîng CORBA, tham chiÕu lªn c¸c ®èi tîng ®ã vµ göi yªu cÇu tõ c¸c servant t¬ng øng.
Bé ®iÒu hîp ®èi tîng chuÈn ®Þnh nghÜa trong CORBA lµ POA (Portable Object Adapter ) nã cung cÊp c¸c ®Æc trng cÇn thiÕt ®Ó kÝch ho¹t c¸c servant, ®Ó cã thÓ thÝch øng víi c¸c lo¹i ORB ®îc cung cÊp bëi nhiÒu h·ng kh¸c nhau. Trong khi BOA ( Basic Object Adapter) còng lµ mét bé ®iÒu hîp ®èi tîng nhng nã g¾n víi tõng lo¹i ORB cña h·ng cung cÊp nã. Díi ®©y ta chØ xÐt POA .
POA
Manager
ORB
POA
Servants
Yªu cÇu
øng dông Server
Mèi quan hÖ gi÷a ORB, POA vµ c¸c servant
Mét øng dông server cã thÓ chøa nhiÒu thÓ hiÖn POA ®Ó hç trî c¸c ®èi tîng CORBA víi c¸c ®Æc tÝnh kh¸c nhau ,hoÆc hç trî nhiÒu d¹ng thùc thi servant . Tuy nhiªn tÊt c¶ c¸c øng dông server ®Òu cã Ýt nhÊt mét POA gäi lµ Root POA . Díi ®©y ta chØ giíi thiÖu c¸ch sö dông c¬ b¶n cña Root POA cÇn thiÕt cho viÖc gi¶i thÝch ¸nh x¹ C++ phÝa server :
C¸c yªu cÇu ®èi tîng CORBA ®îc c tró trong mét øng dông server ®îc göi ®i tõ mét Client vµ chuyÓn ®Õn mét server ORB . Server ORB nµy sÏ gøi c¸c yªu cÇu tíi mét POA mµ t¹i ®ã ®èi tîng ®îc t¹o . POA lóc ®ã göi yªu cÇu tíi servant vµ t¹o ra ®èi tîng ®Ých . Servant thùc hiÖn c¸c yªu cÇu vµ tr¶ vÒ kÕt qu¶ qua POA vµ ORB tíi client .
Server kh«ng thÓ chÊp nhËn bÊt k× yªu cÇu nµo cho ®Õn khi nã yªu cÇu ORB cña nã b¾t ®Çu l¾ng nghe c¸c yªu cÇu ®îc göi tíi . Mét øng dông server cã thÓ cã nhiÒu POA , dßng yªu cÇu ®i vµo mçi POA ®îc ®iÒu khiÓn bëi mét ®èi tîng POA Manager g¾n víi POA ®ã . §Ó yªu cÇu tíi ®îc POA POA Mangager cã thÓ xÕp hµng c¸c yªu cÇu vµ göi sau hoÆc cã thÓ huû bá c¸c yªu cÇu.
Cuèi cïng mçi yªu cÇu CORBA nhËn bëi øng dông server ph¶i ®îc xö lý bëi mét servant.
Chøc n¨ng chÝnh cña ¸nh x¹ C++ phÝa server lµ ®Ó cho phÐp c¸c øng dông thi hµnh c¸c ®èi tîng CORBA sö dông ®èi tîng C++ trong vai trß cña c¸c servant .
C¸c líp C++ phÝa server t¬ng øng víi c¸c giao tiÕp IDL ®îc gäi lµ líp Skeleton . Chóng t¬ng øng víi c¸c líp proxy phÝa client vµ ®îc sinh bëi bé dÞch IDL sang file nguån C++ , råi ®îc dÞch trong øng dông server . Kh«ng nh c¸c líp proxy phÝa client c¸c líp skeleton ®îc më réng ®Ó phôc vô díi vai trß lµ líp c¬ së cho c¸c líp cô thÓ cña øng dông server .
Tõ viÖc dÉn xuÊt c¸c líp servant tõ c¸c líp skeleton ®ã , øng dông server ®îc më réng vµ hoµn tÊt khung skeleton , cho phÐp thiÕt lËp vµ h×nh thµnh c¸c ®èi tîng CORBA.
¸nh x¹ c¸c giao tiÕp
¸nh x¹ C++ phÝa server sinh ra mét líp skeleton riªng cho tõng giao tiÕp IDL . T¬ng tù nh c¸ch mµ tr×nh dÞch IDL sinh ra c¸c file header ®Ó include vµo phÝa client . Tr×nh dÞch IDL thêng sinh c¸c file header chøa c¸c ®Þnh nghÜa líp skeleton . Tªn vµ néi dung cña nh÷ng file sinh ra lµ kh¸c nhau tuú thuéc vµo c¸c nhµ triÓn khai ORB nhng nãi chung mét tr×nh dÞch IDL sinh ra c¶ file header vµ file thùc thi . Nghiªn cøu mét giao tiÕp ®¬n gi¶n díi ®©y:
interface MyObject {
long get_value();
};
File header ph¸t sinh chøa ®Þnh nghÜa líp skeleton nh sau :
Class POA_MyObject public : public virtual PortableServer :: ServantBase {
public :
virtual CORBA::Long get_value() throw
(CORBA::SystemException ) = 0
// . . .
} ;
Mét sè ®iÓm cÇn ph¶i chó ý:
Tªn cña líp skeleton ®îc sinh POA_MyObject phï hîp víi tªn MyObject trong giao tiÕp IDL ngo¹i trõ tiÒn tè POA_ . TiÒn tè POA_ ®îc dïng ®Ó ph©n biÖt c¸c tªn cña c¸c líp C++ ®îc sinh phÝa server víi c¸c tªn phÝa client . Sù ph©n biÖt namespace nµy lµ quan träng v× hÇu hÕt c¸c øng dông CORBA ch¹y kh«ng b×nh thêng ®Òu lµ do c¶ phÝa server víi c¸c ®èi tîng cña nã vµ client víi c¸c ®èi tîng kh¸c . Ngoµi sù kh¸c biÖt trong tªn viÖc cè g¾ng link c¸c líp C++ phÝa client vµ phÝa server trong cïng mét øng dông dÉn ®Õn lçi thêi gian kÕt nèi ( link time-error ) bëi viÖc ®Þnh nghÜa l¹i c¸c tªn . Chó ý lµ tiÒn tè POA_ n»m ë ngoµi cïng . VÝ dô nÕu MyObject ®îc ®Þnh nghÜa trong modul Mod th× tªn ®Çy ®ñ cña nã ®îc sinh trong líp skeleton lµ:
POA_Mod :: MyObject.
Líp skeleton kÕ thõa tõ Portable :: ServantBase lµ líp c¬ së chung cho tÊt c¶ c¸c líp skeleton
Líp skeleton cung cÊp ph¬ng thøc get_value t¬ng øng víi ph¬ng thøc ®îc ®Þnh nghÜa trong IDL .
get_value ®îc khai b¸o thuÇn ¶o (pure virtual) v× vËy líp skeleton POA_MyObject lµ mét líp c¬ së trõu tîng kh«ng thÓ ®îc thùc hiÖn .
get_value bao gåm viÖc chØ ®Þnh mét ngo¹i lÖ mµ nã giíi h¹n kiÓu ngo¹i lÖ C++ ®îc nÐm hîp lÖ. ViÖc chØ râ ngo¹i lÖ ®îc sinh cho ph¬ng thøc phÝa server chèng l¹i ph¬ng thøc ®îc khai b¸o trong c¸c l¬p proxy phÝa client mµ ë ®ã viÖc chØ ®Þnh ngo¹i lÖ lµ tïy chän TÊt c¶ c¸c ph¬ng thøc cµi ®Æt ph¬ng thøc IDL cã thÓ nÐm c¸c ngo¹i lÖ hÖ thèng CORBA ( CORBA system exception ) , ®iÒu nµy cã nghÜa líp c¬ së CORBA :: SystemException ®îc include trong tÊt c¶ c¸c chØ ®Þnh ngo¹i lÖ cña líp skeleton .
3. C¸c líp servant
§Ó t¹o ra mét ®èi tîng CORBA kiÓu MyObject, b¹n ph¶i dÉn xuÊt mét líp servant tõ líp POA_MyObject vµ cµi ®Æt tÊt c¶ c¸c ph¬ng thøc thuÇn ¶o. Xem vÝ dô cña líp servant díi ®©y.
#include “my_object.hh”
class MyObject_impl:public virtual POA_MyObject{
public:
MyObject_impl(CORBA::long init_var):m_value(init_var){}
Virtual CORBA::long get_value () throw (CORBA:System Exception);
Private:
CORBA::long m_value;
MyObject_impl(const MyObject_impl &);
Void operator=(const MyObject_imple &);
};
Cã vµi ®IÓm quan träng cÇn lu ý vÒ líp servant trªn:
Gi¶ sö ch¬ng tr×nh dïng tr×nh dÞch IDL ®Ó dÞch file My_object.idl trong ®ã cã chøa ®Þnh nghÜa IDL cña giao tiÕp MyObject. §Ó s¶n sinh ra file header phÝa server: My_object.hh (tªn cña file header kh«ng ®îc tiªu chuÈn ho¸, v× vËy tªn chÝnh x¸c sÏ thay ®æi theo tr×nh dÞch IDL b¹n dïng). Ch¬ng tr×nh include file header nµy ®Ó thu ®îc khai b¸o cho líp c¬ së POA_Object.
Tªn ®îc chän cho líp servant MyObject_impl phô thuéc hoµn toµn vµo øng dông. Nã cã thÓ lµ bÊt cø tªn g×, miÔn lµ nã kh«ng xung ®ét víi bÊt cø tªn nµo ®îc khai b¸o tríc bëi ¸nh x¹ C++, nh nh÷ng tªn ®îc b¾t ®Çu víi POA_. Theo quy íc ®Æt tªn cho c¸c líp servant víi c¸c hËu tè _impl sao cho chóng ta cã thÓ biÕt ®îc ®ã lµ c¸c líp servant khi nh×n vµo tªn cña líp.
Líp MyObject_Impl thõa kÕ tù líp skeleton POA_myObject vµ n¹p chång hµm thuÇn ¶o get_value lµm cho MyObject mét líp cô thÓ cã thÓ thùc hiÖn.
B¹n b¾t buéc ph¶i cÇn tÊt c¶ c¸c hµm thuÇn ¶o ®îc thõa kÕ trong líp servant bëi v× tr×nh dÞch C++ sÏ kh«ng cho phÐp t¹o c¸c thÓ hiÖn cña nã. Trõ ra r»ng b¹n cã thÓ thªm bÊt cø g× kh¸c b¹n thÊy h÷u Ých ®Ó hç trî viÖc thi hµnh líp servant cña b¹n. VD: b¹n muèn thªm constuctor vµ destructor , thªm hµm thµnh phÇn hoÆc d÷ liÖu thµnh phÇn. B¹n còng cã thÓ thªm phÇn protected hoÆc private. §èi víi vÝ dô trªn chóng ta ®· thªm mét thµnh phÇn d÷ liÖu private lµ m_value cã kiÓu lµ CORBA:: long vµ mét constructor khëi t¹o thµnh phÇn ®ã. Ch¬ng tr×nh còng ®· t¹o c¸c constructor sao chÐp vµ to¸n tö g¸n mÆc ®Þnh private. B»ng c¸ch Êy kh«ng cho phÐp sao chÐp servant cña chóng ta. Thùc tÕ hiÕm khi cÇn cã constructor sao chÐp hoÆc g¸n servant, v× vËy nªn Èn c¸c constructor sao chÐp vµ c¸c khai b¸o mÆc ®Þnh cho c¸c líp servant.
ViÖc thùc thi ph¬ng thøc get_value ®¬n gi¶n lµ tr¶ vÒ gi¸ trÞ m_value.
ViÖc thùc thi hµm get_value qu¸ ®¬n gi¶n ®Õn nçi kh«ng cã ®iÒu khiÓn lçi cã thÓ x¶y ra,v× vËy kh«ng ph¶i nÐn bÊt k× ngo¹i lÖ nµo.
Bëi v× c¸c servant cña ch¬ng tr×nh thõa kÕ c¸c hµm ¶o, nã ph¶i ®îc khai b¸o l¹i c¸c hµm chÝnh x¸c nh chóng ®îc khai b¸o trong líp c¬ së skeleton ph¸t sinh, bao gåm tÊt c¶ c¸c chØ ®Þnh ngo¹i lÖ. H¬n thÕ n÷a c¸c tªn hµm, c¸c ký hiÖu vµ chØ ®Þnh ngo¹i lÖ cho viÖc ®Þnh nghÜa thùc thi servant ph¶I phï hîp chÝnh x¸c víi khai b¸o t¬ng øng. Nõu cã sù kh«ng phï hîp chóng hÇu nh cã thÓ Èn, h¬n thÕ n÷a lµ ®Þnh nghÜa chång, thao t¸c skeleton thõa kÕ. §iÒu nµy cã nghÜa líp servant thõa kÕ c¸c hµm thuÇn ¶o vµ bëi vËy sÏ kh«ng cô thÓ. Cã ®îc nh÷ng khai b¸o vµ ®Þnh nghÜa nµy chÝnh x¸c cã thÓ lµ ®èi tîng sai, v× vËy nhiÒu ch×nh dÞch IDL include c¸c option. Nõu tr×nh dÞch IDL cña b¹n hç trî ®Æc tÝnh ®ã, th× b¹n nªn sö dông nã khi viÕt c¸c líp servant cña b¹n. nÕu thiÕu ®Æc tÝnh nµy b¹n nªn cut vµ Paste khai b¸o ph¬ng thøc víi viÖc thùc thi tõ c¸c file ®îc sinh phÝa server ®Ó tr¸nh lçi. Líp myObject kh¸ ®¬n gi¶n vµ cha ®Çy ®ñ. ThÓ hiÖn cña nã lµ ®Çy ®ñ kh¶ n¨ng cña viÖc h×nh thµnh ®èi tîng CORBA kiÓu MyObject.
4. H×nh thành ®èi tîng
§Ó sö dông thÓ hiÖn cña líp servant MyObject_Impl ®Ó t¹o mét ®èi tîng CORBA, b¹n ph¶I t¹o mét servant MyObject_Impl trong khi h×nh thµnh ®èi tîng CORBA. Chó ý r»ng viÖc t¹o mét servant C++ kh«ng hµm ý viÖc t¹o mét ®èi tîng CORBA, mçi thùc thÓ cña chóng cã nh÷ng ®Ióm riªng vµ vßng ®êi riªng biÖt.
§Ó ®¬n gi¶n vÝ dô sau sÏ chØ râ c¸ch dÔ nhÊt ®Ó t¹o mét servant C++ vµ t¹o lËp mét ®èi tîng CORBA míi b»ng servant ®ã.
// ®Çu tiªn t¹o mét thÓ hiÖn servant
MyObject_impl servant(42);
// tiÕp theo t¹o ®èi tîng CORBA vµ sö dông servant míi t¹o
MyObject_var object= servant_this();
Dßng ®Çu cña ®o¹n code t¹o mét thÓ hiÖn servant vµ thiÕt lËp gi¸ trÞ cña nã lµ 42. ë ®iÓm nµy tÊt c¶ nh÷ng g× ch¬ng tr×nh cÇn cã lµ mét ®èi tîng C++ kh«ng kÕt nèi gi÷a servant vµ bÊt k× mét ®èi tîng CORBA ®· ®îc t¹o.
Dßng hai ®o¹n m· lµ lêi gäi hµm _this cña servant,nã thøc hiÖn c¸c bíc sau:
T¹o mét ®èi tîng CORBA díi root POA.
§¨ng kÝ servant cïng víi root POA khi thùc thi cho ®èi tîng míi.
T¹o mét tham chiÕu ®èi tîng cho ®èi tîng míi.
Tr¶ vÒ tham chiÕu ®èi tîng.
Hµm _this ®îc cung cÊp bëi líp skeleton ®o¹n m· díi sÏ cho biÕt líp POA_MyObject ®îc sinh.
Cho bÊt k× líp skeleton POA_A miªu t¶ giao tiÕp IDL. Vµ gi¸ trÞ tr¶ vÒ cña hµm POA_A::_this lµ A_ptr, kiÓu tham chiÕu ®èi tîng C++ cho giao tiÕp A. theo vÝ dô tríc kiÓu tr¶ vÒ cña hµm this lµ MyObject_ptr. Bëi v× lêi gäi hµm _this chÞu tr¸ch nhiÖm ®¶m b¶o CORBA::release cuèi cïng ®îc gäi kiÓu tham chiÕu ®èi tîng ®îc tr¶ vÒ chóng ta ®· g¸n gi¸ trÞ tr¶ vÒ cho biÕn MyObject_var. Trong vÝ dô trªn ®èi tîng CORBA ®îc t¹o bëi hµm _this lµ mét ®èi tîng tån t¹i ng¾n ngñi. §èi tîng CORBA tån t¹i ng¾n ngñi bëi v× nã rµng buéc víi thêi gian tån t¹i cña POA mµ trong ®ã nã ®îc t¹o ra. Tuy nhiªn hµm _this cã thÓ cung cÊp c¸ch thøc t¹o khu«n d¹ng nµy cña viÖc dÞch vô ®¨ng kÝ nÕu POA cña servant ®îc t¹o víi c¸ch thøc hîp lý.
TËp chuÈn cña c¸ch thøc ®îc hç trî bëi root POA ®îc thiÕt kÕ râ rµng ®Ó cho phÐp hµm _this ®îc sö dông theo kiÓu nµy.
5. Server main
§Ó hoµn tÊt øng dông server ®¬n gi¶n cña ch¬ng tr×nh, ch¬ng tr×nh ph¶i cung cÊp mét hµm main nh sau:
#include “my_objects.hh”
#include “iostream.h”
int main(int argc, char *args[])
{ // khëi t¹o ORB
CORBA::ORB_var orb=CORBA::ORB_init(argc, argv);
// LÊy tham chiÕu ®Õn Root POA
CORBA::Object_var obj = orb->resolve_inittial_references(“Root POA”);
Portable Server::POA_var poa=PortableServer::POA::_narrow._.
Các file đính kèm theo tài liệu này:
- P0138.doc