This document was uploaded by user and they confirmed that they have the permission to share
it. If you are author or own the copyright of this book, please report to us by using this DMCA
report form. Report DMCA
I. Lịch sử ra đời của Corba Nếu bạn là một lập trình viên, bạn sẽ hiểu được công việc nặng nhọc khi phải viết mã lệnh cho chương trình. Cách thiết kế chương trình theo mô hình thủ tục ( top-down procedural hay thủ tục trên-xuống) dần dần được thay thế bằng mô hình hướng đối tượng khoa học và hiệu quả hơn. Lập trình hướng đối tượng đã chứng minh tính đúng đắn và sức mạnh của nó trong việc thiết kế các hệ thống lớn cũng như dễ dàng trong việc nâng cấp và bảo trì mã lệnh. Ngày nay, hầu như mọi ngôn ngữ lập trình đều hỗ trợ và thấm nhuần tư tưởng đối tượng. Mở đầu là Smalltalk, C++, Object Pascal, Delphi, Visual Basic tiếp đến là các hệ quản trị cơ sở dữ liệu Visual Foxpro, Access, SQLserver, Oracle… và như bạn đã thấy Java là ngôn ngữ ra đời sau nhưng lại thuần đối tượng nhất. Trong Java mọi thứ, mọi nơi, mọi khái niệm đều qui về đối tượng. Tuy nhiên lại nảy sinh một bất đồng lớn giữa các ngôn ngữ lập trình. Đó là các đối tượng thiết kế bằng ngôn ngữ nào thì sau khi biên dịch ra mã nhị phân (binary) chỉ có mã lệnh tương ứng của ngôn ngữ đó mới có khả năng truy xuất được đối tượng. Đối tượng viết bằng C++ không dễ dàng truy xuất được từ mã lệnh Delphi hay Visual Basic một cách tự nhiên. Ngay cả đối tượng viết bằng Java cũng khó lòng gọi được từ các ngôn ngữ lập trình khác (mặc dù đã có một số kỹ thuật như sử dụng thư viện liên kết động DLL, gọi các hàm thư viện native… nhưng đó không phải là giải pháp toàn vẹn). Java ra đời với mong muốn các ứng dụng hay đối tượng viết bằng Java có thể chạy được mọi lúc mọi nơi trên mọi hệ điều hành (và cho đến nay có thể nói Sun Microsystem hầu như đã thực hiện được mong ước của mình với sự nổi tiếng của Java). Tuy nhiên, Java không thể thay thế các ngôn ngữ lập trình khác được. Không thể bắt mọi lập trình viên trên thế giới đều chuyển sang viết Java trong khi có hàng trăm triệu dòng mã lệnh của chương trình cũng như thư viện đã được thiết kế và xây dựng từ các ngôn ngữ “tiền bối” khác (điển hình là C/C++ hay Pascal) đang hoạt động rất hiệu quả. Tuy nhiên các nhà lập trình luôn mong muốn tìm được 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 đã được coi như là “quốc tế ngữ” trong giới ngôn ngữ lập trình. II.Corba là gì? CORBA, hoặc là Common Object Request Broker Architecture (tạm dịch là Kiến trúc môi giới gọi các đối tượng thông dụng), là một kiến trúc chuẩn cho các hệ đối tượng phân tán. Nó cho phép một tập các đối tượng hỗn hợp, phân tán siêu tương tác với nhau.
1
1.OMG OMG (Object Management Group) là một tổ chức quốc tế được hình thành từ hơn 700 công ty và tổ chức khác nhau, bao gồm hầu hết các nhà phát triển, các đại lý chính của công nghệ đối tượng phân tán; bao gồm platform, cơ sở dữ liệu, và các nhà cung cấp ứng dụng cũng như công cụ phần mềm và các nhà phát triển hợp nhất. 2. Các mục tiêu, đặc trưng thiết kế CORBA: 2.1.Các mục tiêu của Corba: Khi xây dựng kiến trúc Corba, các nhà thiết kể mong đáp ứng được một số những đặc điểm sau: ♦ Khả năng độc lập về: -
Nền phần cứng (hardware platform).
-
Ngôn ngữ lập trình.
-
Hệ điều hành.
-
Môi giới yêu cầu đối tượng cụ thể.
-
Thứ bậc của phân tán đối tượng.
♦ Tính trong suốt trong liên kết của Corba: -
Định vị đối tượng trong suốt.
-
Cho phép các đối tượng tạo ra các lời triệu gọi và nhận kết quả trả lại một cách trong suốt.
-
Tương tác với các đối tượng từ xa giống như đối tượng cục bộ: + Giữa các host khác nhau. + Các môi trường phân tán không đồng bộ.
-
Corba sử dụng cơ chế môi giới yêu cầu đối tượng ORB để định vị các đối tượng.
♦ Corba kiến trúc mở: Tại sao? -
IDL – Ngôn ngữ định nghĩa giao diện hạt nhân ngôn ngữ trong CORBA.
-
Định nghĩa giao diện IDL được các ngôn ngữ phát triển ứng dụng như C++, Java,… sử dụng để triệu gọi các đối tượng từ xa như ngôn ngữ, nền – platform và trong suốt trong định vị đối tượng. ( Các ngôn ngữ từ xa có thể không được cài đặt ngôn ngữ giống như các đối tượng cục bộ).
♦ Tính đồng nhất: Các đối tượng của Corba có tính đồng nhất: -
Server Corba có thể chứa nhiều giao diện với nhiều trường hợp.
2
-
Tham chiếu đối tượng xác định một trường hợp cụ thế.
Tham chiếu đối tượng Corba có thể thực hiện liên tục: -
Một số đối tượng Corba chỉ tồn tại nhất thời và chỉ được sử dụng bởi một Client.
-
Một số đối tượng Corba có thể được chia sẻ và tồn tại lâu dài theo quy trình nghiệp vụ và chính sách được quyết định khi đóng gói “destroy” đối tượng.
Các đối tượng của Corba có thể định vị (cấp phát) lại: -
Tham chiếu đối tượng không quan tâm đến vị trí của đối tượng.
-
Đối tượng Corba có thể được định vị lại bởi Amid hoặc chạy lại chương trình.
-
Thực thi Corba có thể hỗ trợ giao dịch được định vị lại.
Corba hỗ trợ để các đối tượng phục hồi, sao chép lại khi cùng tham chiếu đối tượng giống nhau trên các vùng nhớ khác nhau. 2.2.Đặc trưng thiết kế CORBA: IDL-interface
Object
♦ CORBA làm việc với giao diện: -
Tất cả các đối tượng Client chỉ có thể truy cập đối tượng CORBA thông qua giao diện.
-
Sự phân chia giữa các Interface và các implementation cho phép tạo ra đa các thực thi –implementations cho một giao diện.
♦ Đặc trưng Server CORBA: -
Khi nói đến server ta phải rằng đang nói đến quy trình trên server chứ không phải máy server.
-
Một hoặc nhiều quá trình server CORBA có thể chạy trên cùng một máy.
-
Mỗi quá trình server CORBA chứa một hoặc nhiều trường hợp về đối tượng CORBA, một hoặc nhiều giao diện CORBA.
3
Process A
Process B
Process C
Machine X
Machine Y
Đối tượng Corba có thể định vị đến các quá trình, trong quá trình khác nhau trên cùng một máy hoặc các quá trình khác nhau trên những máy khác nhau. 3.Kiến trúc CORBA CORBA định nghĩa một kiến trúc cho các đối tượng phân tán. Mô hình CORBA cơ bản đó là một yêu cầu dịch vụ của một đối tượng phân tán. Mọi thứ khác được định nghĩa bởi OMG là dưới dạng mô hình cơ bản này. Các dịch vụ mà một đối tượng cung cấp được định nghĩa bởi giao tiếp (interface) của nó. Các giao tiếp được định nghĩa trong Interface Definition Language (IDL) của OMG. Các đối tượng phân tán được xác định bởi các tham chiếu đối tượng, được định kiểu bởi các giao tiếp IDL. Trong kiến trúc chung Corba thì ORB (Object Request Broker) là thành phần trọng tâm và hạt nhân. ORB được coi là highway ( xa lộ hay còn gọi là băng thông) thực thi tất cả các vấn đề truyền thông của CORBA. Khi một ứng dụng Client muốn sử dụng dịch vụ do Server cung cấp cần: -
Thứ nhất: thực hiện được tham chiếu đến đối tượng trên Server cung cấp.
-
Thứ hai: xử lý các yêu cầu tham chiếu đối tượng, cho phép các thành phần ứng dụng kết nối lẫn nhau.
Nói chung nhiệm vụ của ORB là: -
Sắp xếp thứ tự dữ liệu.
-
Quản lý định vị đối tượng.
-
Truyền tải yêu cầu đến đối tượng trên Server.
-
Trả lại kết quả cho Client.
4
IDL compiler
Naming Service Interface Repository
Implementation Repository Object Implementation
Client
IDL skel IDL stubs
DLL
ORB interface
Object adapter
ORB Core
GIOP/IIOP
I/O subsystem Kernel Network Adapters
DSI
I/O subsystem Kernel Network Adapters
Network
Hình sau biểu diễn một yêu cầu. Một client giữ một tham chiếu đối tượng đến một đối tượng phân tán. Tham chiếu đối tượng được định kiểu bởi một giao tiếp. Trong hình dưới thì tham chiếu đối tượng được định kiểu bởi giao tiếp Rabbit. Object Request Broker (ORB), đưa yêu cầu đến đối tượng và trả về một số kết quả cho client. Trong hình yêu cầu jump trả về một tham chiếu đối tượng được định kiểu bởi giao tiếp AnotherObject.
Hình 1: Kiến trúc một yêu cầu cơ bản của CORBA. 4. IDL(Interface definition language - Ngôn ngữ định nghĩa giao diện). 4.1. Sơ lược về IDL: 5
♦ Interface: giao diện cho một đối tượng, được định nghĩa bằng ngôn ngữ IDL. ♦ Các đối tượng của ngôn ngữ lập trình tuân theo đặc tả Idl thì được xem như là các đối tượng Corba. IDL được coi như là ngôn ngữ chương trình độc lập và chỉ chứa các mô tả dữ liệu. Nó là ngôn ngữ chung của chương trình phần mềm. Ví dụ ứng dụng IDL: Struct resultStatus int status; // trạng thái string result; ; //kết quả struct Content string YourMission;//nội dung cần học string IDUniver;//trường đã học string Major;//chuyên ngành string Certificate;//bằng cấp string Gramark;//xếp loại bằng int Grayear; // năm tốt nghiệp interface ContentProvider exception NoServer string message;; ::ResultStatusHandleTransaction ( inout::ContentTransaction);;
Server Skeleton Compile IDL Client Stub
IDL description
translator
Call procedure
translator
Client Stub
Server Stub
Result
Result
Reply
Reply
request
Transport Layer
Hình 2:
Call procedure
Transport Layer
Ngôn ngữ đặc tả IDL dịch sang ngôn ngữ lập trình
6
♦ Phía Client được che đi các chi tiết cài đặt của các đối tượng. Việc thay đổi cài đặt object sẽ không làm thay đổi ở phía client. ♦ Clinet và server độc lập với kiến trúc và bus Corba. Để có được sự độc lập đó, các mô tả IDL sẽ được tham chiếu sang các môi trường lập trình (stub và skeleton). ♦ Client sử dụng các stub cục bộ để truy nhập đến các đối tượng. Các stub cho phép xây dựng các lời gọi đến các skeleton thông qua môi trường truyền dẫn là bus Corba. ♦Phía skeleton sẽ tiếp nhận các lời gọi này và gửi đến các object cục bộ. 4.2. Các khái niệm cơ bản: -
Tên tệp: *.IDL
-
Dẫn hướng biên dịch giống như C++: #include, #define, #ifdef …#endif
-
Chú thích giống C++: /*…*/ và //…
-
Tên (identifier): tên bắt đầu bằng chữ thông thường, tuy nhiên khi đã được định nghĩa thì phải dùng thống nhất.
-
Từ khóa là những chữ thường.
• Modules -
Module là một khối có tên cho phép nhóm các tên lại trong cùng một không gian tên ( tương tự như namespace trong C++):
module Mymodule { // các định nghĩa IDL // hoặc các module con }; -
Các module có thể được mở lại (trong cùng một tệp hoặc trong tệp khác)
-
Phạm vi của các tên giống như trong cấp phân cấp các module.
-
Một tên có thể được định nghĩa lại trong các module con.
-
Tên có thể được truy nhập từ bên ngoài thông qua toán tử :: như trong C++ Ví dụ: Module Module1 { typedef long Longmod_1; module Module_1
• Các kiểu dữ liệu cơ bản: Bảng sau đây miêu tả chi tiết các đặc điểm của các kiểu dữ liệu cơ sở:
Type
values
Size (en bits)
Short
-3278…+3278
16 bits có dấu
Long
-211…+211-1
32 bít có dấu
Unsigned short
0…65535
16 bít không dấu
Unsigned long
0…212-1
32 bít không dấu
Float
IEEE single
32 bít
Double
IEEE double
64 bít
Octet
0…255
8 bít
Char
ISO-latinh
8 bít
8
Wchar
International format
String
ISO –latinh
Variable
Wstring
International format
Variable
Boolean
True or false
Không xác định
• Khai báo const và typedef: • Sequence -
Sequence định nghĩa một dãy các giá trị cùng kiểu, có thể bị chặn hoặc không: sequence sequence
Ví dụ: Typedef sequence<short> dayso; -
Có thể định nghĩa các sequence lồng nhau:
Typedef sequence<squence>matran;
• Kiểu mảng: -
Kiểu mảng định nghĩa một dãy đúng N phần tử:
Type
identifiant[N];
Type
identifiant[N1] [N2]…[Nn]
Ví dụ: Typedef float [100] [100] matrixA; -
Trong thực tế ta nên hạn chế sử dụng kiểu mảng trong IDL do thiếu tính linh động và gặp nhiều khó khăn khi ánh xạ snag một vài ngôn ngữ khác chẳng hạn như C++
• Unions (kết hợp) Ví dụ: union ParametreOptionnels switch(boolean) { case true: string value1;
9
case false: short value2; }; Trong thực tế nên tránh sử dụng union do: -
Khó khăn khi tham chiếu sang các ngôn ngữ khác.
-
Không theo quan điểm hướng đối tượng.
•Interfaces: Cách khai báo: Interface NomInterface : Parent1, parent2 {…}; Interface NomInterface { // định nghĩa các: // - constants //- types //- exceptions //- attributes //- operations };
Cách khai báo: attribut Type nomAttribut; readonly attribute Type nomAttribut; Trong thực tế ta nên tránh khai báo các thuộc tính vì : -
Việc truy nhập đến một thuộc tính (sửa đổi) không thể tạo ra một exception của người sử dụng.
-
Định nghĩa các thuộc tính trong interface không phải là cách tiếp cận hướng đối tượng.
• Inheritance: Ví dụ: Interface fichier { void lire (out octet octetLu) ; void ecrire(in octet octetEcrit) ; }; Interface fichier_executable : fichier { short executer (in string argsList) ; }; 5. Ánh xạ giữa ngôn ngữ IDL và Java (IDL mapping to Java) Đồ án này chủ yếu giúp bạn tìm hiểu Java nên tốt nhất là chúng ta hãy tìm hiểu việc ánh xạ từ ngôn ngữ đặc tả IDL sang ngôn ngữ lập trình Java. Dưới đây là tập các ánh xạ của ngôn ngữ IDL trong CORBA tương đương với các kiểu dữ liệu và từ khoá có trong Java. IDL CORBA
JAVA
Module
Package
Interface
Interface, helper class, holder class
Constant
Public static final
Boolean
Boolean
11
Char, wchar
Char
Octet
Byte
String, wstring
Java.lang.string
Short, unsigned short
Short
Long, unsigned long
Int
Long long, unsigned long long
Long
Float
Float
Double
Double
Enum, struct, union
Class
Sequence, array
Array
Exception
Class
Operation
method
Như vậy, IDL không có các cấu trúc điều khiển như if, while, do, for…IDL chỉ là ngôn ngữ đặc tả. Trong ngôn ngữ đặc tả mọi việc diễn ra tương tự như khi bạn khai báo biến, mô tả đối tượng, kiểu record… không cần phải có các cấu trúc lệnh điều khiển. Java cung cấp cho bạn công cụ dùng để chuyển đổi qua lại giữa khai báo CORBA sang khai báo Java và ngược lại như sau: Để chuyển một lớp interface nào đó của java sang đặc tả IDL bạn dùng lệnh o rmic –idl YourObject.class Để chuyển một đặc tả IDL sang khai báo interface tương ứng trong Java bạn dùng lệnh o idlj YourObject.idl rmic và idlj là hai chương trình .exe nằm trong thư mục [JAVA_HOME]\bin. Ví dụ ánh xạ giữa CORBA và Java:
12
CORBA IDL
JAVA
Module {
Package Math;
interface Mathlibrary {
Public interfaces
long add (
MathLibrary {
in long x,
Int add ( int x,
in long y ); long subtract (
Int y ); Int subtract ( int x,
in long x;
Int y );
in long y );
Int divide ( int x,
long divide ( in long x,
Int y ); Int multiple( int x,
in long y ); long multiple (
Int y ); string About (
in long x, in long y );
string version ); }
string About ( in string version ); };
Như vậy khái niệm package trong Java tương đương với module trong CORBA. CORBA đưa ra từ khoá in cho các biến truyền vào phương thức theo trị (tương tự từ khoá out dùng để lấy trị trả về).
13
Chương 2. Corba và công nghệ lập trình phân tán I.Tổng quan về hệ phân tán. Hệ phân tán trong đó các chức năng và dữ liệu được phân tán trên nhiều trạm, được kết nối với nhau thông qua một mạng máy tính. Hoặc có thể nói: Hệ phân tán bao gồm tập các máy tính tự trị được nối với nhau bởi mạng máy tính và các thiết bị được cái đặt phần mềm được thiết kế để cung cấp một môi trường tích hợp và nhất quán (phần mềm của hệ phân tán).
Hình 3: Kiến trúc cơ bản của hệ phân tán. Hệ phân tán cho phép con người có thể hợp tác, phối hợp các hoạt động một cách mềm dẻo và hiệu quả. Mục tiễu chính của hệ phân tán có thể được thể hiện thông qua: chia sẻ tài nguyên( resource sharing), tính mở (openness), tính đồng thời(concurency), khả năng mở rộng (scalability),tính chịu lỗi (faul-tolerance), tính trong suốt (transparency) Chia sẻ tài nguyên: trong hệ phân tán, phần cứng, phần mềm, dữ liệu có thể được chia sẻ dễ dàng giữa nhiều người sử dụng. Tài nguyên được thiết kể tập trung hoặc phân tán; tương tác theo kiến trúc client-server. Tài nguyên được tổ chức thành các đối tượng và đựoc định danh duy nhất trong hệ thống. Một số ưu điểm của hệ phân tán: 1.Tính mở. Khả năng bổ sung, mở rộng phần cứng, các chức năng mới không ảnh hưởng tới các phần khác trong hệ thống cũ. 14
2.Tính tương tranh. Nhiều tính trình cùng tồn tại trên một máy tính đơn gọi là tính tương tranh. Ở một hệ phân tán rất dễ xảy ra xử lý song song là do: - Nhiều người sử dụng đồng thời gọi các lệnh, cùng tương tác với chương trình ứng dụng. - Nhiều tiến trình chạy trên server mỗi tiến trình xử lý một yêu cầu. Các truy cập, cập nhật tương tranh phải được thống nhất. 3.Khả năng mở rộng. Khả năng mở rộng quy mô hệ thống một cách dễ dàng mà phải thay đổi hệ thống cũ một cách ít nhất. Đây là đặc tính quan trọng trong quá trình phát triển nhanh của mạng interNetwork. 4.Tính chịu lỗi. Các hệ thống đôi khi bị lỗi, lỗi xảy ra có thể do phần cứng hay phần mềm dẫn đến chương trình có thể chạy sai hoặc dừng trước khi hoàn thành yêu cầu. Tính chịu lỗi cho phép phần vẫn có thể hoạt động được khi xảy ra các lỗi nhỏ, tính chịu lỗi luôn đi kèm với phục hồi dữ liệu đó là yêu cầu phục hồi dữ liệu trong thời gian sơm nhất. Thiết kế hệ thống mày tính có khả năng chịu lỗi có hai cách tiếp cận: - Tăng độ dư thừa tại nguyên: Giải pháp này tăng độ đề phòng của hệ thống khi xảy ra lỗi. - Giải pháp phần mềm: Phầm mềm có khả năng sao lưu một cách thường xuyên, có khả năng phát hiện lỗi và sửa lỗi sớm. Hệ phân tán cung cấp mức độ cao của tính thường trực trong khả năng chịu lỗi phần cứng. Khi một trạm bị hỏng người sử dụng có thể di chuyển tới trạm khác để làm việc. 5.Tính trong suốt. khả năng che dấu sự rời rạc của hệ thống. Hệ thống ISO chỉ ra có 8 loại trong suốt: - Trong suốt lỗi - Trong suốt truy cập - Trong suốt tương tranh - Trong suốt định vị - Trong suốt lặp. - Trong suốt di trú.
15
- Trong suốt mở rộng. Nhược điểm của hệ phân tán • Tính phức tạp: Hệ phân tán phức tạp hơn hệ tập trung • Tính bảo mật: Hệ phân tán dễ bị tấn công từ bên ngoài • Khả năng quản lý: Hệ phân tán đòi hỏi hệ quản lý hiệu quả Không dự đoán trước: Không thể biết được những phản hồi do tổ chức hệ thống và mạng trả về. II. Corba và mô hình phân tán 1. Chương trình môi giới trung gian ORB( Object Request Broker) Java dựa vào máy ảo để tạo nên tiếng nói chung giữa tất cả ứng dụng viết bằng ngôn ngữ Java. Tương tự Corba cũng cần có một nền tảng để liên kết các đối tượng. Các đối tượng sau khi được xây dựng bằng những ngôn ngữ lập trình khác nhau muốn triệu gọi được nhau phải thông qua trình môi giới trung gian của Corba gọi là ORB (Object request broker : Trình môi giới các yêu cầu của đối tượng). ORB là một dịch vụ phân tán thực thi yêu cầu đến các đối tượng ở xa. Nó định vị đối tượng ở xa trên mạng, gửi yêu cầu đến đối tượng, chờ kết quả và khi sẵn sằng thì gửi các kết quả này trở lại cho client. ORB thực thi vị trí trong suốt. Chính xác là cơ chế yêu cầu giống nhau được sử dụng bởi client và đối tượng CORBA mà không quan tâm đến vị trí của đối tượng. Nó có thể nằm trong một bộ xử lí với client, hoặc ở bất kì nơi nào. ORB thực thi các ngôn ngữ lập trình độc lập với các yêu cầu. Client đưa ra một yêu cầu được viết bởi một ngôn ngữ lập trình có thể khác với ngôn ngữ lập trình viết trong đối tượng CORBA. ORB thực hiện việc dịch cần thiết giữa các ngôn ngữ lập trình. Các liên kết ngôn ngữ được định nghĩa cho tất cả các ngôn ngữ lập trình thông dụng. Hình 3 là cơ chế triệu gọi lẫn nhau của các đối tượng viết bằng C++, Delphi, Java thông qua ORB. Như vậy cụ thể thì ORB gọi được phương thức của các đối tượng cài đặt bằng các ngôn ngữ khác nhau như thế nào? Đó là nhờ ngôn ngữ đặc tả IDL mà ta đã tìm hiểu ở trên. Các đối tượng cho dù được cài đặt bằng bất kì ngôn ngữ nào nếu như tuân thủ theo đặc tả IDL đều được xem là đối tượng CORBA. Tuy không cài đặt bản thân đối tượng nhưng dựa vào đặc tả IDL ORB sẽ biết được tên phương thức cần gọi, kiểu đối số truyền cho phương thức, trị trả về của phương thức gọi. Với những thông tin này, ORB có thể triệu gọi phương thức mà đối tượng cài đặt (Hình 4). ORB là hoàn toàn trong suốt (transparent) với lập trình viên (hay người
16
sử dụng đối tượng). Bạn gọi đối tượng của Java trong C++ hay Delphi hoàn toàn theo cách tự nhiên như bạn gọi đối tượng được xây dựng từ chính ngôn ngữ gốc.
ORB
ORB
C++ CORB A Object
Java CORB A Object
Mạng ORB
Delphi CORB A Object Hình 4 : Triệu gọi đối tượng CORBA thông qua trình môi giới ORB. Khả năng “trong suốt” không chỉ giới hạn giữa các đối tượng trên cùng một máy mà còn được mở rộng giữa các đối tượng nằm ở bất kỳ đâu trên thế giới thông qua kết nối mạng. Đối tượng của bạn viết bằng Java đặt trên một máy tại Việt Nam có thể được gọi bởi một đối tượng ở Châu Mỹ (“bên kia đại dương”) cài đặt bằng C++. Với khả năng trên, CORBA quả là mang lại điều kỳ diệu cho thế giới lập trình. CORBA mở cửa để các lập trình viên có thể xích lại gần nhau hơn, tạo nên một thể thống nhất của mô hình lập trình hướng đối tượng.
Mạng Internet
IDL ORB
ORB IDL
C++ CORB A Object
Java CORB A Object
Hình 5 : ORB giao tiếp với đối tượng thông qua các thông tin đặc tả IDL. 17
2. Cơ chế làm việc của ORB: ORB cũng dùng khái niệm lớp trung gian _Stub và _Skel tương tự như cách làm việc của các đối tượng RMI. Thật sự _Stub và _Skel là hai lớp trung gian được sinh ra từ trình biên dịch dựa vào đặc tả IDL. Bạn không cần phải viết mã lệnh cho lớp _Stub và _Skel. Đây là công việc của các nhà cung cấp và thiết kế ORB. Hình 6 là cơ thế hoạt động của trình môi giới ORB liên lạc giữa trình khách và đối tượng CORBA trên máy chủ. Thường thì việc cài đặt đối tượng CORBA trên máy chủ và triệu gọi đối tượng từ trình khách được thực hiện như sau: Phần cài đặt đối tượng CORBA trên máy chủ ♦Đặc tả đối tượng X bằng ngôn ngữ IDL của CORBA ♦Chuyển đặc tả X thành mô tả của một ngôn ngữ cụ thể (chẳng hạn dùng trình biên dịch idlj.exe để chuyển đặc tả của đối tượng X sang ngôn ngữ Java). Dựa vào đặc tả IDL yêu cầu trình biên dịch tạo ra lớp trung gian _Skel. Cài đặt đối tượng X bằng Java. Phần kết nối với đối tượng từ máy khách ♦Sử dụng đặc tả IDL của đối tượng X yêu cầu trình biên dịch tạo ra lớp trung gian _Stub. Tuỳ theo ngôn ngữ muốn viết ở máy khách mà ta sử dụng trình biên dịch thích hợp. Ví dụ nếu bạn muốn viết trình khách bằng ngôn ngữ C++ bạn có thể dùng trình biên dịch idl2cpp.exe để tạo ra lớp _Stub dành cho chương trình C++ triệu gọi đối tượng CORBA. ♦Khi trình khách triệu gọi đối tượng chủ, thực tế lời gọi sẽ được chuyển qua lớp _Stub trên máy khách, gửi đến trình môi giới ORB. Trình ORB trên máy khách sẽ kết nối với trình ORB trên máy chủ (theo giao thức IIOP). Trình ORB trên máy chủ chuyển lời gọi cho lớp trung gian _Skel trên máy chủ. Cuối cùng thì đối tượng thì đối tượng CORBA trên máy chủ sẽ thực thi phương thức của nó.
C++ Client
Java CORB
Lớp trung gian Stub
Lớp trung gian Skel
IIOP
ORB
18
ORB
Hình 6 : Giao tiếp giữa trình khách và đối tượng CORBA trên máy chủ. 3.Giao thức IIOP Giao tiếp giữa ORB trên máy khách và ORB trên máy chủ được xây dựng dựa trên giao thức mang tên IIOP (Interoperate Internet Object Protocol). Giao thức này do tổ chức Corba đề xướng. Nó làm nền cho tất cả các đối tượng có thể trò chuyện được với nhau trên mạng Internet một cách dễ dàng. Hiện nay giao thức IIOP được dùng khá phổ biến thậm chí còn vượt trội hơn cả giao thức triệu gọi từ xa RMI của Java (Java gọi giao thức RMI mà các máy ảo có thể dùng trò chuyện được với các đối tượng ở xa là JRMP- Java Remote Method Protocol).
HTTP
HTML & Java Applet
Web server Proxy server
Java Enabled Web Browser HTML Document Java Applet
IIOP
Naming serice
Relational Database
Distributed Objects JDBC ODBC DBMS_ specific
Hình 7 : Truy cập Internet CORBA thông qua IIOP
19
4. Quá trình phát triển ứng dụng cơ bản sử dụng Corba : -
Cài đặt các interface (các đối tượng trên server) dựa trên việc kế thừa bộ khung (skeleton) sinh ra bởi bộ dịch IDL.
-
Việc phát triển của phía client bắt đầu dựa trên một tham chiếu (reference) đến đối tượng. Việc gọi các method của các đối tượng từ xa cũng giống như khi gọi các phương thức cục bộ.
Tuy nhiên cũng cần chú ý một số điểm khi gọi phương thức từ xa : -
Thời gian gọi ( tính theo ms, 1000 lần chậm hơn khi gọi cục bộ).
-
Việc giao tiếp giữa client và server sẽ phải tính đến các exception ( Các exception này phải được phía client chấp nhận và xử lý).
IDL defs
IDL compile r
Stubs
Skeletons Java
Client prog
compile r
Client program
Object impl
Server program
Stub
Skeleton
ORB Hình 8 : Quá trình phát triển ứng dụng Corba.
20
Để hiểu kỹ thêm về quá trình phát triển ứng dụng Corba chúng ta hãy cùng nhau nghiên cứu cách thức một đối tượng phân tán một phương thức được chia sẻ giữa một client CORBA và một server để thực hiện ứng dụng “Hello World » cổ điển. Ta sẽ xây dựng chương trình Hello World cổ điển như là một ứng dụng phân tán, với cả applet và các client ứng dụng. Gồm các bước sau : 4.1.Định nghĩa một giao tiếp từ xa. Bạn định nghĩa một giao tiếp cho một đối tượng từ xa sử dụng IDL. Sử dụng IDL thay vì sử dụng Java bởi vì bộ biên dịch idlj tự động ánh xạ từ IDL, sinh ra tất cả các file nguồn skeleton và stub Java, cùng với mã cơ sở hạ tầng để kết nối đến ORB. Hơn nữa, với việc sử dụng IDL, tạo cho người phát triển khả năng cài đặt các client và server trong một số ngôn ngữ biên dịch CORBA khác. Để ý rằng nếu bạn đang cài đặt một client cho một dịch vụ CORBA đang tồn tại, hoặc một server cho một client đang tồn tại, bạn sẽ nhận được các giao tiếp IDL từ người cài đặt – ví dụ nhà cung cấp hoặc đại lý dịch vụ. Sau đó bạn sẽ chạy bộ biên dịch idlj trên toàn bộ giao tiếp đó và theo các bước này.
• Tạo file Hello.idl Để tạo file Hello.idl ta làm các bước sau : Tạo một thư mục mới, có tên là Hello, cho ứng dụng này Khởi động trình soạn thảo ưa thích của bạn và tạo ra file có tên Hello.idl trong thư mục trên. Trong file, nhập vào các đoạn mã để định nghĩa giao tiếp sau : module HelloApp { interface Hello { string sayHello(); }; }; Ghi file lại.
•Hiểu file idl. OMG IDL là một ngôn ngữ khai báo đúng nghĩa được thiết kế cho việc đặc tả các giao tiếp thao tác độc lập ngôn ngữ lập trình, bao gồm C, C++, Smalltalk, COBOL, Ada, và Java. Khi được ánh xạ thì mỗi câu lệnh trong OMG IDL được biên dịch đến một câu lệnh tương ứng theo ngôn ngữ lập trình đã lựa chọn. Có thể 21
sử dụng lệnh idlj để ánh xạ một giao tiếp IDL sang Java và cài đặt lớp client. Khi bạn ánh xạ cùng file IDL đó sang C++ và cài đặt server cùng ngôn ngữ này, thì client Java và server C++ tương tác qua ORB như là chúng được viết trong cùng một ngôn ngữ. IDL cho Hello World thực sự là rất đơn giản; giao tiếp đơn của nó chỉ có một thao tác đơn. Bạn chỉ cần thực hiện ba bước sau : ♦Khai báo module IDL CORBA Một module CORBA là một namespace hoạt động như là một container cho các giao tiếp và khai báo liên quan. Nó gần tương tự như gói trong Java. Mỗi câu lệnh trong module IDL được ánh xạ sang một câu lệnh trong gói Java. Câu lệnh module có dạng như sau: module HelloApp { // Subsequent lines of code here. }; Khi bạn biên dịch IDL, lệnh module sẽ tự động sinh ra một lệnh package trong mã Java. ♦Khai báo giao tiếp Giống như các giao tiếp Java, các giao tiếp CORBA khai báo API kết giao một đối tượng với các đối tượng khác. Mỗi câu lệnh interface trong IDL được ánh xạ đến một câu lệnh interface Java. Trong file Hello.idl, interface có dạng sau: module HelloApp { interface Hello // These {
// are the // interface
};
// statement.
};
22
♦Khi bạn biên dịch IDL, câu lệnh này sẽ tạo ra một lệnh interface theo mã Java. Các lớp client và server sẽ cài đặt giao tiếp Hello theo nhiều cách. Khai báo các thao tác. Các thao tác CORBA là các hành vi mà các server hứa thực hiện vì lợi ích của client gọi nó. Mỗi một lệnh thao tác trong IDL sinh ra một lệnh phương pháp tương ứng trong giao tiếp Java đã sinh ra. Trong file Hello.idl lệnh thao tác có dạng: module HelloApp { interface Hello { string sayHello(); // This line is the operation statement. }; }; Ứng dụng nhỏ của chúng ta chỉ có một thao tác, vì thế Hello.idl đã hoàn thành. 4.2.Biên dịch giao tiếp từ xa. Khi bạn chạy bộ biên dịch idlj trên file định nghĩa giao tiếp của bạn, nó sinh ra phiên bản Java của giao tiếp, cũng là các mã lớp cho stubs và sketetons tạo khả năng cho ứng dụng của bạn kết nối được ORB. Lệnh idlj đọc file OMG IDL và tạo ra các file Java theo yêu cầu. Bộ biên dịch idlj ngầm định tạo ra chỉ các ràng buộc về phía client. Nếu bạn muốn có cả bên phía client và skeletons server (như chương trình Hello World này), thì bạn phải sử dụng tuỳ chọn –fall khi chay bộ biên dịch idlj. a. Di chuyển đến dấu nhắc prompt b. Chuyển đến thư mục chứa file Hello.idl c. Nhập vào lệnh biên dịch: idlj -fall Hello.idl Nếu bạn liệt kê nội dung của thư mục, bạn sẽ thấy một thư mục gọi là HelloApp được tạo ra và chứa sáu file. Mở Hello.java trong trình soạn thảo văn bản của bạn. Hello.java được xem như là một giao tiếp chữ kí và được sử dụng như là một kiểu chữ kí trong các khai báo phương pháp khi các giao tiếp của các dạng đặc tả được sử dụng trong các giao tiếp khác. Nó có dạng như sau: package HelloApp;
23
/** * HelloApp/Hello.java * Generated by the IDL-to-Java compiler (portable), version "3.0" * from Hello.idl */ public interface Hello extends HelloOperations, org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity { } // interface Hello Với một giao tiếp đơn giản như thế này thì ta dễ dàng nhận ra các câu lệnh IDL được ánh xạ sang các câu lệnh Java như thế nào. IDL Statement module HelloApp interface Hello
Java Statement package HelloApp; public interface Hello
Một việc gây ngạc nhiên đó là lệnh extends. Tất cả các đối tượng CORBA được lấy từ org.omg.CORBA.Object để đảm bảo tồn tại các hàm CORBA yêu cầu. Các mã yêu cầu được sinh ra bởi idlj; bạn không cần phải làm bất cứ một ánh xạ nào khác. Trong các phiên bản trước của idlj (được biết như là idltojava), các giao tác được định nghĩa trong giao tiếp IDL cũng sẽ tồn tại trong file này. Bắt đầu với J2SDK, ánh xạ IDL-to-Java đặt tất cả các thao tác định nghĩa trong giao tiếp IDL trong operations interface (giao tiếp thao tác), HelloOperations.java. Giao tiếp các thao tác này được sử dụng trong ánh xạ phía server và như là một cơ chế để cung cấp các cuộc gọi tối ưu cho các client và server tập hợp cùng nhau. Đối với Hello.idl, file này có dạng sau: package HelloApp;
/**
24
* HelloApp/HelloOperations.java * Generated by the IDL-to-Java compiler (portable), version "3.0" * from Hello.idl */ public interface HelloOperations { String sayHello (); } // interface HelloOperations Bởi vì chỉ có một thao tác được xác định trong giao tiếp này, nên dễ dàng để xem các câu lệnh IDL ánh xạ sang các câu lệnh Java: IDL Statement
Java Statement
string sayHello();
String sayHello();
d. Tìm hiểu đầu ra của lệnh idlj Biên dịch idlj tạo ra một số các file. Số các file thực sự tạo ra tuỳ thuộc vào các lựa chọn được chọn khi file IDL được biên dịch. Các file được sinh ra cung cấp các hàm chuẩn, vì thế bạn có thể bỏ qua nó cho đến khi bạn triển khai và chạy chương trình của mình.Các file được sinh ra bởi biên dịch idlj với tuỳ chọn –fall là: _HelloImpBase.java Lớp trừu tượng này là server skeleton, chứa các hàm CORBA cơ bản cho server. Nó cài đặt giao tiếp Hello.java. Lớp server HelloServant extends _HelloImpBase. _HelloStub.java Lớp này là client stub, cung cấp các hàm CORBA cho client. Nó cài đặt giao tiếp Hello.java. Hello.java Giao tiếp chữ kí chứa phiên bản Java của giao tiếp IDL. Giao tiếp Hello.java mở rộng org.omg.CORBA.Object, cung cấp hàm đối tượng CORBA chuẩn. Nó cũng mở rộng IDLEntity, và được sử dụng như là dạng chữ kí trong các khai báo
25
phương pháp khi các giao tiếp của các dạng đặc tả được sử dụng bởi các giao tiếp khác. HelloHelper.java Lớp final này cung cấp hàm hỗ trợ, đặc biệt là phương pháp narrow()được yêu cầu để ép kiểu các đối tượng tham chiếu CORBA đến các kiểu thích hợp. HelloHolder.java Lớp final này giữ một thành viên mẫu public của kiểu Hello. Nó cung cấp các thao tác cho các đối số out và inout mà CORBA cho phép, nhưng không ánh xạ dễ dàng sang các ngữ nghĩa của Java. HelloOperations.java Giao diện các thao tác này chưa đơn phương pháp sayHello().Ánh xạ IDL-to-Java đặt tất cả các thao tác xác định trong giao tiếp IDL trong file này. Giao tiếp thao tác được sử dụng trong ánh xạ phía server và như là một cơ chế để cung cấp các cuộc gọi tối ưu để tập hợp các client và server. Khi bạn viết giao tiếp IDL, bạn đã làm tất cả các lập trình yêu cầu để tạo ra các file này cho ứng dụng phân tán của bạn. Các bước tiếp theo là cài đặt các lớp client và server. 4.3.Cài đặt Server. Khi bạn chạy biên dịch idlj, bạn có thể sử dụng skeletons nó sinh ra để đặt cùng với ứng dụng server của bạn. Thêm vào để cài đặt các phương pháp của giao tiếp từ xa, mã server bao gồm một cơ chế để bắt đầu ORB và chờ phản hồi từ client ở xa. Lớp server có phương pháp main() : Tạo ra một mẫu ORB. Tạo ra một mẫu servant (cài đặt đối tượng Hello CORBA) và nói với ORB về nó. Nhận một tham chiếu đối tượng cho một naming context để đăng kí đối tượng CORBA mới. Đăng kí đối tượng CORBA mới trong naming context với tên “Hello”. Chờ đợi phản hồi của đối tượng mới. a. Tạo ra HelloServer.java Khởi động trình soạn thảo văn bản của bạn và tạo ra file tên là HelloServer.java trong thư mục chính, Hello. Nhập các dòng mã sau cho HelloServer.java trong file text: // The package containing our stubs. 26
import HelloApp.*; // HelloServer will use the naming service. import org.omg.CosNaming.*; // The package containing special exceptions thrown by the name service. import org.omg.CosNaming.NamingContextPackage.*; // All CORBA applications need these classes. import org.omg.CORBA.*;
public class HelloServer { public static void main(String args[]) { try{ // Create and initialize the ORB ORB orb = ORB.init(args, null); // Create the servant and register it with the ORB HelloServant helloRef = new HelloServant(); orb.connect(helloRef); // Get the root naming context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(objRef);
27
// Bind the object reference in naming // Make sure there are no spaces between "" NameComponent nc = new NameComponent("Hello", ""); NameComponent path[] = {nc}; ncRef.rebind(path, helloRef); // Wait for invocations from clients java.lang.Object sync = new java.lang.Object(); synchronized(sync){ sync.wait(); } } catch(Exception e) { System.err.println("ERROR: " + e); e.printStackTrace(System.out); } } }
class HelloServant extends _HelloImplBase { public String sayHello() { return "\nHello world!!\n"; } } Ghi và đóng HelloServer.java lại. b. Tìm hiểu HelloServer.java 28
Ta sẽ giải thích các dòng trong HelloServer.java, miêu tả sự hoạt động và sự cần thiết của nó. Thực hiện các cài đặt cơ bản. Cấu trúc của một chương trình server CORBA giống như hầu hết các ứng dụng khác: bạn nhập các gói thư viện cần thiết, khai báo lớp server, định nghĩa một phương pháp main(), và điều khiển ngoại lệ. -
Nhập các gói cần thiết
Đầu tiên là nhập các gói cần thiết cho lớp server: // The package containing our stubs. import HelloApp.*; // HelloServer will use the naming service. import org.omg.CosNaming.*; // The package containing special exceptions thrown by the name service. import org.omg.CosNaming.NamingContextPackage.*; // All CORBA applications need these classes. import org.omg.CORBA.*; -
Khai báo lớp Server
Bước tiếp theo là khai báo lớp server: public class HelloServer { // The main() method goes here. } -
Định nghĩa phương thức main()
Mọi ứng dụng Java đều cần một phương thức main(). Nó được khai báo trong phạm vi của lớp HelloServer: public static void main(String args[]) { 29
// The try-catch block goes here. } -
Điều khiển các ngoại lệ hệ thống CORBA.
Bởi vì tất cả các chương trình CORBA đều có thể gặp ngoại lệ hệ thống CORBA khi đang chạy, tất cả các hàm main()đều được đặt trong môt khối try-catch. Khối try-catch được đặt trong hàm main() như sau: try{ // The rest of the HelloServer code goes here. } catch(Exception e) { System.err.println("ERROR: " + e); e.printStackTrace(System.out); } Tạo ra một đối tượng ORB. Giống như một ứng dụng client, một server CORBA cũng cần một ORB cục bộ. Mọi server tạo ra một ORB và đăng kí các đối tượng servant của nó vì thế ORB có thể tìm ra server khi nó nhận được một phản hồi. Biến ORB được khai báo và khởi động trong khối try-catch. ORB orb = ORB.init(args, null); Quản lí đối tượng Servant. Một server là một tiến trình đưa ra một hay nhiều các đối tượng. servant cài đặt giao tiếp sinh ra bởi idlj và thực hiện thực sự các công việc của các thao tác trên giao tiếp đó. HelloServer của ta cần một HelloServant. -
Đưa ra một đối tượng Servant
Ta đưa ra một đối tượng servant trong khối try-catch, chỉ sau lời gọi init() như sau: HelloServant helloRef = new HelloServant();
30
Bước tiếp theo là kết nối servant đến ORB, vì thế ORB có thể nhận ra các phản hồi trên chúng và đưa chúng đến đúng servant: orb.connect(helloRef); -
Xác định lớp Servant.
Đoạn cuối của HelloServer.java, ngoài lớp HelloServer, ta xác định lớp cho đối tượng servant. class HelloServant extends _HelloImplBase { // The sayHello() method goes here. } Servant là một lớp con của _HelloImplBase vì thế nó kế thừa các hàm CORBA chung được tạo ra bởi bộ biên dịch. Tiếp theo ta khai báo phương thức sayHello(): public String sayHello() { // The method implementation goes here. } Cài đặt phương thức sayHello() có dạng như sau: return "\nHello world!!\n"; Làm việc với COS Naming HelloServer làm việc với dịch vụ naming để tạo ra tính sẵn có cho các thao tác của đối tượng servant cho client. Server cần một tham chiếu đối tượng để đặt tên dịch vụ, vì thế tự nó có thể đăng kí và đảm bảo rằng các phản hồi trên giao tiếp Hello được chỉ đường đến đối tượng servant của nó. -
Có được Initial Naming Context.
Trong khối try-catch, sau khi đưa ra servant, ta gọi orb.resolve_initial_references()để nhận một tham chiếu đối tượng cho name server.
31
org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); Chuỗi “NameService” được định nghĩa cho tất cả ORBs CORBA. Khi bạn gặp chuỗi này, ORB trả về một đối tượng naming context đó là một tham chiếu đối tượng cho name service. -
Ép kiểu tham chiếu đối tượng
Như cùng với tất cả các tham chiếu đối tượng CORBA, objRef là một đối tượng CORBA chung. Để sử dụng nó như là một NamingContext, bạn phải ép kiểu nó thành một kiểu thích hợp. Lời gọi narrow() chỉ sau câu lệnh trên: NamingContext ncRef = NamingContextHelper.narrow(objRef); Tại đây bạn đã thấy ứng dụng của lớp được idlj sinh ra helper. Đối tượng ncRef bây giờ là một org.omg.CosNaming.NamingContext và bạn có thể sử dụng nó đến naming service và đăng kí với server, như trong mục sau. -
Đăng kí Servant với Name Server
Chỉ sau lời gọi narrow(), ta tạo ra một thành phần NameComponent mới: NameComponent nc = new NameComponent("Hello", ""); Câu lệnh này tạo ra một trường id của nc là “Hello” và thành phần kind là chuỗi rỗng. Đảm bảo là không có dấu cách nào giữa “”. Bởi vì đường dẫn đến Hello có một đơn nhân tố, ta tạo ra mảng nhân tố đơn mà NamingContext.resolve cần cho nó: NameComponent path[] = {nc}; Cuối cùng, ta qua đường dẫn và đối tượng servant đến naming service, gắn đối tượng servant cho id “Hello”: ncRef.rebind(path, helloRef); Bây giờ, khi client gọi resolve(“Hello”) trên initial naming context, naming service trả về tham chiếu đối tượng servant Hello. Chờ phản hồi Các mục trước miêu tả mã để server sẵn sàng, mục tiếp theo giải thích mã để ngầm định server chờ yêu cầu các dịch vụ từ client. Mã sau, nằm cuối (nhưng trong) khối try-catch, chỉ ra cách hoàn thành nó:
32
java.lang.Object sync = new java.lang.Object(); synchronized(sync){ sync.wait(); } c. Biên dịch Hello World Server Bây giờ ta sẽ biên dịch HelloServer.java vì thế ta có thể sửa lỗi. Đến thư mục Hello. javac HelloServer.java HelloApp/*.java Chạy trình biên dịch Java cho HelloServer.java
Chỉnh sửa các lỗi trong file và dịch lại nếu cần thiết. Các file HelloServer.class và HelloServant.class được sinh ra trong thư mục Hello. 4.4.Cài đặt Client. a. Tạo file HelloClient.java Để tạo file HelloClient.java: 1. Mở trình soạn thảo, tạo file tên HelloClient.java trong thư mục project, Hello. 2. Gõ vào đoạn code sau: import HelloApp.*;
// The package containing our stubs.
import org.omg.CosNaming.*; // HelloClient will use the naming service. import org.omg.CORBA.*;
// All CORBA applications need these classes.
public class HelloClient { public static void main(String args[]) { try{ // Create and initialize the ORB 33
ORB orb = ORB.init(args, null); // Get the root naming context org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(objRef); // Resolve the object reference in naming // make sure there are no spaces between "" NameComponent nc = new NameComponent("Hello", ""); NameComponent path[] = {nc}; Hello helloRef = HelloHelper.narrow(ncRef.resolve(path)); // Call the Hello server object and print results String Hello = helloRef.sayHello(); System.out.println(Hello); } catch(Exception e) { System.out.println("ERROR : " + e); e.printStackTrace(System.out); } } } 3. Lưu và đóng file HelloClient.java b. Giải thích Phần này giải thích rõ từng dòng code trong file HelloClient.java, mô tả đoạn code đó làm gì, cũng như tại sao nó lại cần cho ứng dụng • Thực hiện cài đặt cơ bản Mô hình của một chương trình khách CORBA cũng giống như các chương trình Java khác. Ta phải nhập vào các gói thư viện cần thiết, khai báo lớp, xây dựng hàm main, và xử lý các exception. 34
o Nhập các gói cần thiết Đầu tiên, ta sẽ nhập các gói cần thiết cho lớp client import HelloApp.*;
// The package containing our stubs.
import org.omg.CosNaming.*; // HelloClient will use the naming service. import org.omg.CORBA.*;
// All CORBA applications need these classes.
o Khai báo lớp Client Bước tiếp theo là khai báo lớp client public class HelloClient { // The main() method goes here. } o Xây dựng hàm main() Tất cả các ứng dụng Java đều cần hàm main(). Hàm này được khai báo trong phạm vi lớp HelloClient, như sau: public static void main(String args[]) { // The try-catch block goes here. } o Xử lý các lỗi hệ thống Bởi vì tất cả các chương trình CORBA đều có thể phát sinh các lỗi hệ thống trong thời gian chạy, do đó tất cả các hàm main() đều phải được đặt trong khối trycatch. Cách giải quyết lỗi đơn giản là in tên các lỗi và vết stack của các lỗi đó ra màn hình để ta có thể theo dõi được cái gì thực hiện sai. Khối try-catch được đặt bên trong hàm main(). try{ // Add the rest of the HelloClient code here. } catch(Exception e) { System.out.println("ERROR : " + e); e.printStackTrace(System.out); 35
} • Tạo một đối tượng ORB Trình khách CORBA cần một đối tượng ORB để thực hiện các hành vi và công việc IIOP của nó. Tất cả các trình khách đều khởi tạo đối tượng org.omg.CORBA.ORB. Đối tượng ORB được khai báo và khởi tạo bên trong khối try-catch. ORB orb = ORB.init(args, null); Phương thức tĩnh init() của lớp ORB cần hai đối số. Đối số thứ nhất dùng để nhận các tùy chọn từ dòng lệnh nếu có. Đối số thứ hai là các tùy chọn do lập trình viên chỉ định. Nếu cả hai đối số này đều mang giá trị null thì ORB sẽ sử dụng các thông số hệ thống mặc định. • Tìm trình chủ Hello Bây giờ ứng dụng đã có một ORB. Nó có thể yêu cầu ORB định vị dịch vụ nó cần, trong trường hợp này là trình chủ Hello. Có một số cách để trình khách CORBA nhận được tham chiếu đối tượng gốc; ứng dụng khách của ta sẽ sử dụng dịch vụ COS Naming được tạo ra bởi tổ chức OMG và được cung cấp cùng với Java IDL. o Lấy về tham chiếu gốc của dịch vụ Bước đầu tiên trong việc sử dụng dịch vụ naming là lấy về tham chiếu gốc. Trong khối try-catch, sau khi khởi tạo ORB, ta sẽ gọi hàm để lấy về tham chiếu gốc orb.resolve_initial_references() đến tên của trình chủ. org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); Xâu “NameService” được định nghĩa cho tất các các đối tượng CORBA ORB. Khi ta truyền xâu này, ORB sẽ trả lại tham chiếu gốc của tên dịch vụ. o Co lại tham chiếu đối tượng Giống như tất cả các tham chiếu đến đối tượng CORBA, objRef là một đối tượng CORBA tổng quát. Để sử dụng nó như một đối tượng NamingContext, ta phải chuyển nó về kiểu đối tượng tường minh. NamingContext ncRef = NamingContextHelper.narrow(objRef); Ở đây ta đã sử dụng lớp helper, tương tự như HelloHelper. Đối tượng ncRef bây giờ là một đối tượng org.omg.CosNaming.NamingContext và ta có thể dùng nó để truy nhập vào dịch vụ naming và tìm các dịch vụ khác. Chúng ta sẽ thực hiện nó ở bước tiếp theo. o Tìm dịch vụ
36
Các tên có cấu trúc khác nhau, tùy thuộc vào việc thực thi các dịch vụ naming. Do đó, các trình chủ giải quyết các tên phức tạp bằng cách của đối tượng NameComponent. Từng NameComponent giữ một thành phần riêng, hoặc một nguyên tố, của một tên. Một mảng các đối tượng NameComponent có thể lưu giữ các đường dẫn cụ thể và đầy đủ đến đối tượng trên bất cứ một file hay một hệ thống đĩa nào. Để tìm trình chủ Server, ta cần một NameComponent để giữ tên của trình chủ Hello. NameComponent nc = new NameComponent("Hello", ""); Câu lệnh này gán cho trường id của nc giá trị là “Hello” và trường kind là xâu rỗng. Để đảm bảo chắc chắn là xâu rỗng, ta không nhập gì ở khoảng trống giữa “”. Bởi vì đường dẫn đến đối tượng Hello chỉ có một thành phần, ta phải tạo ra một mảng thành phần đơn chứa nc. Phương thức NamingContext.resolve() yêu cầu mảng này để làm việc. NameComponent path[] = {nc}; Cuối cùng, ta sẽ truyền đường dẫn đến hàm resolve() của dịch vụ naming để lấy về tham chiếu đến đối tượng chủ Hello, và chuyển kiểu nó thành đối tượng Hello. Hello helloRef = HelloHelper.narrow(ncRef.resolve(path)); Ở đây, ta sử dụng lớp HelloHelper. Phương thức resolve() trả lại một đối tượng CORBA tổng quát. Do đó, ta phải chuyển nó về kiểu Hello, đó là tham chiếu đối tượng ta cần để thực hiện phần công việc còn lại. o Gọi thao tác sayHello() Lời gọi đối tượng CORBA giống như lời gọi trong các đối tượng địa phương khác. String Hello = helloRef.sayHello(); Cuối cùng chúng ta in kết quả của lời gọi ra màn hình System.out.println(Hello); • Dịch file HelloClient.java -
Chuyển sang thư mục Hello
-
Chạy chương trình biên dịch Java:
javac HelloClient.java HelloApp/*.java -
Sửa lỗi nếu có
37
4.5.HelloClient.class được tạo ra trong thư mục HelloBắt đầu ứng dụng. Khi bạn đã cài đặt một server và một client, bạn có thể bắt đầu name service, sau đó là server tiếp đó là client. Khởi động Java IDL Name Server. Ta dùng: start tnameserv -ORBInitialPort 1050 Từ cửa sổ prompt thức hai, ta đánh: start java HelloServer -ORBInitialPort 1050 Từ cửa sổ prompt thứ ba, ta đánh: java HelloClient -ORBInitialPort 1050 Client in ra chuỗi từ server trên dòng lệnh command: Hello world!!
Hình 9 : Một đối tượng phân tán một phương thức được chia sẻ giữa một client CORBA và một server. 5.CORBA là một chuẩn cho các đối tượng phân tán Một trong các mục đích của đặc tả CORBA đó là các client và các thực thi CORBA là khả chuyển. Đặc tả CORBA định nghĩa một application programer’s interface (API) cho các client của một đối tượng phân tán cũng như một API cho quá trình thực thi của một đối tượng CORBA. Điều này có nghĩa là các mã được viết cho một sản phẩm CORBA của một nhà cung cấp nào đó có thể, với nỗ lực ít nhất, được viết lại để làm việc với sản phẩm của một nhà cung cấp khác. Tuy nhiên, thực tế là các sản phẩm CORBA trên thị trường hôm nay chỉ có các client CORBA là mang tính khả chuyển còn các thực thi đối tượng vẫn cần một số thay đổi để có thể đi từ sản phẩm CORBA này đến sản phẩm khác. CORBA 2.0 tích hợp thêm thao tác giữa các phần (interoperability) như là một mục đích của đặc tả. Nói riêng, thì CORBA 2.0 định nghĩa một giao thức mạng, gọi là IIOP (Internet Inter-ORB Protocol), cho phép các client sử dụng các sản phẩm CORBA từ bất cứ một nhà cung cấp nào để giao tiếp với các đối tượng 38
khác sử dụng sản phẩm CORBA từ một kì một nhà cung cấp khác. IIOP thực hiện trên Internet, hay nói đúng hơn là thông qua một số thực thi TCP/IP. Thao tác giữa các phần trong một hệ phân tán còn quan trọng hơn cả tính khả chuyển. IIOP được sử dụng trong các hệ khác thậm chí không cố gắng cung cấp CORBA API. Một cách cụ thể thì IIOP được sử dụng như một giao thức chuyển tải cho một phiên bản của Java RMI (vì thế được gọi là “RMI over IIOP”). Bởi vì EJB được định nghĩa về mặt RMI, nên nó cũng có thể được sử dụng IIOP. Các server ứng dụng khác nhau đang có trên thị trường sử dụng IIOP nhưng không thể hiện toàn bộ CORBA API. Bởi vì chúng đểu sử dụng IIOP, các chương trình được viết cho các API khác nhau này có thể tương tác giữa các phần và với các chương trình được viết cho CORBA API. 6. Dịch vụ quản lý tên COS NAMING của CORBA: 6.1. Tìm hiểu về JNDI Khi bạn muốn sử dụng một đối tượng nào đó trong cuộc sống, đầu tiên bạn cần phải biết là nơi mà vật đó đang được cất giữ(hay đặt để). Làm thế nào để tìm ra đối tượng? Làm thế nào để lưu lại đối tượng sau khi sử dụng?… Mỗi đối tượng trong thế giới thực đều được mang một tên gọi nhất định. Ít ra hai vật thể khác nhau cũng có thể phân biệt với nhau qua tên gọi (các vật thể trùng nhau về tính chất cũng có thể phân biệt qua một đặc trưng khác biệt nào đó mà trong môi trường cơ sở dữ liệu ra vẫn quen gọi là khóa). Mặt khác, cần phải có một hệ thống lưu trữ những tên gọi này theo cách nào đó để khi cần bạn có thể dựa theo tên để tìm ra đối tượng thật dễ dàng. Khái niệm trên chúng ta gặp rất nhiều trong cuộc sống. Như danh bạ điện thoại là một hệ thống lưu trữ tên dựa vào số điện thoại của người dùng. Bản đồ là một hệ thống tên gắn liền với các thành phố, đường xá. Hệ thống file là một dịch vụ quản lý tên của thư mục và tập tin trên đĩa, DNS là dịch vụ gắn liền địa chỉ IP của máy tính với một tên gợi nhớ nào đó. Một dịch vụ quản lý tên đều quy định cách thức để bạn lưu trữ và gắn tên cho đối tượng. Ví dụ trong danh bạ điện thoại bạn lưu tên gắn với số điện thoại theo thứ tự ACB. Trên bản đồ, tên các thành phố đường xá được phân theo quận huyện. Hệ thống file thường lưu tập tin và thư mục theo cấu trúc hình cây. Với mỗi cách lưu trữ như vậy, dịch vụ quản lý tên luôn cung cấp cho bạn cách thức tìm kiếm và đặt tên cho đối tượng cần quản lý một cách nhất định. Tổng quát hóa JAVA đặc tả một tập hợp các hàm API dùng để phục vụ cho việc quản lý và lưu trữ tên đối tượng. Các hàm API này gọi là JNDI (Java Naming Directory Interface). JNDI cung cấp cách đặt tên, lưu trữ và tìm kiếm đối tượng một cách tổng quát nhất. Với JNDI bạn có thể gọi cùng phương thức để tìm kiếm tập tin trên hệ thống file, thư mục, tên địa chỉ qua mạng Internet, tên các đối tượng RMI, CORBA,…JNDI chỉ đưa ra các đặc tả ở dạng interface. Các dịch vụ nào muốn sử dụng JNDI thì phải cài đặt giao tiếp do Java quy định. 6.2. JNDI và dịch vụ COS Naming của CORBA:
39
Dựa vào đặc tả JNDI của Java, Corba xây dựng một cơ chế lưu trữ tên và tham chiếu của đối tượng. Corba phân ra khái niệm NamingContext và NamingComponent tương tự như khái niệm file và thư mục mà ta vẫn quen thuộc. NamingContext là một đối tượng có khả năng dẫn tham chiếu đến NamingComponent hay NamingContext khác (NamingContext đóng vai trò như một thư mục). NamingContext được đặt tên dựa vào NamingComponent. NamingComponent là một thành phần chứa tên (tương tự nhãn hoặc tên file) có khả năng ràng buộc tên với một đối tượng bất kỳ nào đó (đối tượng này phải là đối tượng Corba). NamingComponent và NamingContext quan hệ với nhau theo cấu trúc hình cây tương tự cấu trúc cây thư mục của hệ thống file trên đĩa. Hình 10 là một ví dụ về cách lưu trữ của dịch vụ COS Naming trong Corba. Dịch vụ này chính là chương trình tnameserv.exe mà ta sẽ có dịp tìm hiểu qua khi cài đặt chương trình.
Market
NameComponent
Object A
Stock Toys
Object B
NameContext Fruit
Shelf
Object C
Book
Panel
Đối tượng NameCoponent
Đối tượng NameContext
40
Tên ràng buộc của đối tượng
Đối tượng được ràng buộc
Hình10. Mô hình ràng buộc và lưu trữ đối tượng của dịch vụ COS Naming Như ta đã thấy ở hình 10, Market là một đối tượng NamingContext. Nó cho phép bạn tìm ra 3 thành phần tên: Stock, Shefl và Panel. Bản thân Stock, Shelf là hai NamingContext. Stock chứa 2 thành phần mang tên Toys và Fruit. Shelf chứa một thành phần mang tên Book. Đối tượng Object A được ràng buộc với tên Toys trong khi đối tượng Object B, Object C được ràng buộc bởi tên Fruit và Book. Một đối tượng không chỉ được ràng buộc bởi một tên mà có thể nhiều tên. Ví dụ cả Panel và Book cùng ám chỉ đến đối tượng Object C. Điều này tương tựh như trong Windows, một tập tin trên đĩa có thể được tham chiếu đến bằng nhiều shortcut hay trong Unix/Linux, một tập tin vật lý có thể được tham chiếu bằng nhiều link khác nhau. Bây giờ ta thử hình dung COS Naming là một cây thư mục. Nếu đứng từ Market để tham chiếu đến đối tượng Object A ta phải chỉ đường dẫn như sau: Market\Stock\Toys. Muốn tham chiếu đến Object C, ta chỉ đường dẫn Market\Panel hoặc Market\Shelf\Book. Tuy nhiên nếu ta đang đứng ở vị trí Stock ta chỉ cần tham chiếu đến đối tượng Objetc A theo cách Stock\toys là đủ. Đó chính là khái niệm ngữ cảnh (context) mà ta sẽ gặp trong dịch vụ COS Naming của CORBA. Đối với một đối tượng, tùy theo cntext khác nhau mà ta có thể truy xuất theo tên của đối tượng khác nhau. 7.Các dịch vụ khác CORBA Một phần quan trọng của chuẩn CORBA đó là định nghĩa một tập các dịch vụ phân tán để cung cấp sự tích hợp và sự tương tác của các đối tượng phân tán. Như mô tả trong hình dưới đây, được biết đến như là các CORBA sevices hay COS, được định nghĩa đầu của ORB. Có nghĩa là, chúng được xác định như là các đối tượng CORBA chuẩn với các giao tiếp IDL, đôi lúc được xem đến như là “các dịch vụ đối tượng” (Object Services).
Hình 10 : Kiến trúc COS. Có một số dịch vụ CORBA. Dưới đây ta liệt kê sơ qua về chúng: 41
Dịch vụ
Mô tả
Chu kì vòng đời đối Định nghĩa một đối tượng CORBA được tạo ra, tượng (Object life cycle) xoá, di chuyển, và sao chép như thế nào Naming
Xác định việc đặt các tên cho các đối tượng CORBA
Events
Tách các giao tiếp giữa các đối tượng phân tán
Relationships
Cung cấp các quan hệ n-ary định dạng ngẫu nhiên giữa các đối tượng CORBA.
Externalization
Định toạ độ các di chuyển của các đối tượng CORBA và từ phương tiện truyền thông bên ngoài.
Transactions
Định toạ độ các nguyên tử truy nhập đến các đối tượng CORBA.
Concurrency Control
Cung cấp dịch vụ khoá cho các đối tượng CORBA để có được một sự truy nhập tuần tự
Property
Hỗ trợ liên kết giữa các cặp name-value với các đối tượng CORBA
Trader
Hỗ trợ việc tìm kiếm của đối tượng CORBA dựa trên các thuộc tính miêu tả dịch vụ được cung cấp bởi đối tượng.
Query
Hỗ trợ truy vấn trên các đối tượng
8.Các sản phẩm của CORBA CORBA là một đặc tả. Nó là một hướng dẫn để thực thi các sản phẩm. Một số nhà cung cấp bán các sản phẩm CORBA được viết bằng các ngôn ngữ khác nhau. Các sản phẩm CORBA hỗ trợ ngôn ngữ lập trình Java bao gồm :
ORB Java 2 ORB
Mô tả Java 2 ORB kết hợp cùng với Sun’s Java 2 SDK. Nó thiếu một số đặc tính. 42
VisiBroker cho Java
OrbixWeb
Một ORB Java thông dụng của Insprise Corporation. VisiBroker cũng được nhúng trong các sản phẩm khác. Ví dụ, nó là ORB được nhúng trong trình duyệt Netscape Communicator. Một ORB Java thông dụng của Iona Technologies.
WebSphere
Một server ứng dụng thông dụng với một ORB của IBM
Netscape Communicator
Các trình duyệt Netscape có một phiên bản của VisiBroker nhúng trong chúng. Các applet có thể đưa ra yêu cầu trên các đối tượng CORBA mà không cần tải các lớp ORB vào trình duyệt. Chúng đã có sẵn ở đó.
Various free shareware ORBs
hoặc
Các thực thi CORBA đối với các ngôn ngữ khác nhau có sẵn để tải về trên các trang web từ các nguồn khác nhau.
43
Chương 3: Chương trình ứng dụng. Trang Web nghe nhạc online .a Mục đích của trang Web -
Minh họa cho việc lập trình web sử dụng CORBA trong Java
.b Kiến trúc hệ thống
Web browser
Invokes
Loads Corba Server Corba Client Servle
Web Server
Acesses
Data
Invokes
Trình khách CORBA ở đây là một servlet. Mọi giao tiếp với servlet đều thông qua giao thức HTTP, do đó người sử dụng có thể sử dụng một trình duyệt web chuẩn không có giao thức IIOP để triệu gọi đến đối tượng từ xa. Servlet được thực hiện trên Web server sẽ nhận yêu cầu HTTP, sau đó tạo IIOP để triệu gọi đối tượng từ xa. Khi nó nhận được câu trả lời của IIOP, nó sẽ gửi câu trả lời HTTP tương ứng đến trình khách . Ưu điểm của cơ cấu này là kiểu giao tiếp này không bị ngăn cản bởi các hàng rào an ninh. Thậm chí khi trình khách HTTP là một applet thì cũng không có một ngăn cấm nào với applet được áp dụng bởi vì giao tiếp là giao tiếp với Web server của applet. Hơn nữa, các yêu cầu HTTP được cho phép đi qua nhiều tường lửa. Servlet hoạt động như một cổng IIOP.
44
.c Tại sao lại sử dụng CORBA trong xây dựng chương trình? Nội dung lưu trữ trong máy chủ: -
Các file nhạc
-
Cơ sở dữ liệu lưu trữ danh sách các bài hát, và đường dẫn của chúng
-
Các đối tượng để lấy về danh sách và nội dung file nhạc
Quá trình thực hiện như sau: Người sử dụng đăng nhập vào trang Web, là một trình khách Corba Servlet. Trình khách sẽ gửi yêu cầu triệu gọi đối tượng lấy danh sách bài hát đến trình chủ CORBA. Trình chủ CORBA thông qua Web Server sẽ gửi đối tượng mà trình khách cần đến trình khách. Danh sách các bài hát sẽ được hiển thị trên trang Web của người sử dụng. Người sử dụng sẽ chọn bài hát và gửi yêu cầu lấy nội dung của file nhạc này. Trình chủ CORBA sẽ tiếp tục gửi đối tượng file nhạc về cho trình khách. Trình khách sẽ thực hiện play file nhạc này.
Vậy làm cách nào để có thể triệu gọi đối tượng nhạc đến máy khách? Và khi mà máy chủ và máy khách sử dụng hai ngôn ngữ lập trình không giống nhau (ví dụ. máy chủ sử dụng ngôn ngữ C++, còn máy khách sử dụng ngôn ngữ Java), làm cách nào để tìm được tiếng nói chung giữa hai ngôn ngữ này? Đó chính là lý do mà ta chọn sử dụng CORBA trong ứng dụng. CORBA với mục đích sử dụng trong kỹ thuật lập trình phân tán và đáp ứng mong muốn tìm được tiếng nói chung cho tất cả các ngôn ngữ lập trình hiện có, hoàn toàn có thể đáp ứng được các yêu cầu trên. .d Các bước xây dựng trang Web -1 Đặc tả đối tượng CORBA bằng ngôn ngữ IDL module song{ struct SongInfo{ long id; string tittle; 45
Đối tượng SongInfo dùng để chứa các thông tin về một bài hát, bao gồm mã bài hát, tên bài hát, đường dẫn đến file nhạc.
Đối tượng Song : o Dùng để lấy về danh sách các bài hát thuộc thể loại nhạc trẻ, nhạc Pop, nhạc Rock …. o Lấy về đối tượng bài hát được chọn
-
Đối tượng FileInterface: dùng để tải file nhạc về máy khách
-2 Cài đặt đối tượng CORBA Song bằng ngôn ngữ Java Với mục đích minh họa cho việc sử dụng CORBA trong Java nên ngôn ngữ lập trình được sử dụng trong trình khách và trình chủ ở đây đều được chọn là Java. • Đối tượng SongManager kế thừa lớp SongPOA public class SongManager extends SongPOA{ 46
… } • Tạo hàm setORB() kết nối đối tượng CORBA với trình môi giới ORB private ORB orb; public void setORB(ORB orb_val){ orb=orb_val; } • Tạo hàm getItem() lấy về đối tượng bài hát được chọn public SongInfo getItem(int id) throws SQLError{ // Kết nối cơ sơ dữ liệu trên máy chủ … // Thực hiện truy vấn lấy về bài hát có mã bài hát tương ứng với mã bài hát được chọn … // Đối tượng được trả về có kiểu SongInfo } • Tạo hàm getPop() lấy về danh sách các bài thuộc thể loại nhạc Pop public boolean getPop(){ // Kết nối cơ sở dữ liệu … // Thực hiện truy vấn lấy về thông tin các bài hát thuộc thể loại nhạc Pop lưu vào đối tượng kiểu SongInfo … // Các đối tượng thu được được lưu vào file “t.tmp” … } • Các hàm getNhactre(), getRock(), … cũng làm tương tự. -3 Cài đặt đối tượng CORBA FileInterface bằng ngôn ngữ Java • Đối tượng FileServant kế thừa lớp FileInterfacePOA public class FileServant extends FileInterfacePOA{ 47
… } •
Tạo hàm setORB() kết nối đối tượng CORBA với trình môi giới ORB private ORB orb; public void setORB(ORB orb_val){ orb=orb_val; } • Tạo hàm downloadFile() để tải file nhạc từ máy chủ về. Nội dung của file nhạc tải về được lưu trong một mảng kiểu byte public byte[] downloadFile(String fileName){ File file = new File(fileName); byte buffer[] = new byte[(int)file.length()]; try { BufferedInputStream input = new BufferedInputStream(new FileInputStream(fileName)); input.read(buffer,0,buffer.length); input.close(); } catch(Exception e) { System.out.println("FileServant Error: "+e.getMessage()); e.printStackTrace(); } return(buffer); }
-4 Viết trình cài đặt đối tượng CORBA trên máy chủ public class SetupServer { … } • Đầu tiên do CORBA cần đến trình môi giới trung gian ORB nên trình đăng ký phải khởi động môi trường này bằng lệnh
48
ORB orb=ORB.init(args,null); • Thực hiện tham chiếu đến RootPOA và kích hoạt POAManager CORBA trong đặc tả mới nhất muốn xây dựng mô hình khả chuyển (portable) cho các đối tượng bằng khái niệm POA (Portable Object Adaptor). POA là lớp chịu trách nhiệm quản lý và kích hoạt đối tượng theo yêu cầu của trình khách. ORB cung cấp cho bạn nhiều lớp POA. Tất cả các lớp POA con đều phải được tạo ra từ POA gốc (gọi là root POA). POA rootpoa=POAHelper.narrow(orb.resolve_initial_references("RootPOA")); rootpoa.the_POAManager().activate(); • Tiếp đến đối tượng CORBA được tạo ra một cách bình thường SongManager manager=new SongManager(); FileServant fileServant=new FileServant(); • Kết nối đối tượng với trình môi giới manager.setORB(orb); fileServant.setORB(orb); • Lấy về tham chiếu của dịch vụ tên org.omg.CORBA.Object nameService = orb.resolve_initial_references("NameService"); • Chuyển tham chiếu về đối tượng NamingContext NamingContext nsContext=NamingContextHelper.narrow(nameService); • Lấy tham chiếu đối tượng từ dịch vụ org.omg.CORBA.Object ref1=rootpoa.servant_to_reference(manager); Song href1=SongHelper.narrow(ref1); org.omg.CORBA.Object ref2=rootpoa.servant_to_reference(fileServant); FileInterface href2=FileInterfaceHelper.narrow(ref2); • Tạo tên của đối tượng NameComponent nc1=new NameComponent("SongManager",""); NameComponent nc2=new NameComponent("FileServant",""); • Tạo đường dẫn lưu tên đối tượng NameComponent path1[]={nc1}; 49
NameComponent path2[]={nc2}; • Yêu cầu dịch vụ ràng buộc đối tượng theo tên nsContext.rebind(path1,href1); nsContext.rebind(path2,href2); • Chờ nhận yêu cầu từ máy khách java.lang.Object obj=new java.lang.Object(); synchronized(obj){ obj.wait(); } -5 Tạo applet nghe nhạc để nhúng vào trang Web public class JMF extends Applet implements ControllerListener { … } -6 Tạo trang Servlet index.java làm trang chủ public class index extends HttpServlet { public void doGet (HttpServletRequest request, HttpServletResponse response) { try { PrintWriter out; response.setContentType("text/html"); out = response.getWriter(); // đoạn tạo giao diện HTML … } catch (Exception e) { System.out.println(e); } } } -7 Tạo các trang link đến • Servlet pop.java public class pop extends HttpServlet { 50
// Hashtable dùng để lưu trữ danh sách các bài hát private Hashtable songs=new Hashtable(); // Các đối tượng CORBA và NamingContext NamingContext nsContext=null; NameComponent nc1=null; Song servant=null; NameComponent nc2=null; FileInterface fileServant=null; // Khởi tạo Servlet public void init(ServletConfig config) throws ServletException { // kết nối đối tượng CORBA với trình môi giới ORB ORB orb = ORB.init(args, null); // Lấy tham chiếu dịch vụ tên org.omg.CORBA.Object nameService = orb.resolve_initial_references("NameService"); nsContext = NamingContextHelper.narrow(nameService); // Tạo tên đối tượng nc1=new NameComponent("SongManager",""); nc2=new NameComponent("FileServant",""); } catch(Exception e) { System.out.println("ERROR : " + e); e.printStackTrace(System.out); } }
public void doGet (HttpServletRequest request, HttpServletResponse response){ // Lấy tham chiếu đối tượng CORBA trên máy chủ NameComponent path1[]={nc1};
51
servant=SongHelper.narrow(nsContext.resolve(path1)); NameComponent path2[]={nc2}; fileServant=FileInterfaceHelper.narrow(nsContext.resolve(path2)); // Đọc nội dung file t.tmp trên máy chủ tải về máy khách, lưu vào file t1.tmp … // Lấy nội dung file t1.tmp cho vào hashtable. … // Hiển thị giao diện HTML … // Lấy nội dung hashtable cho vào list for (Enumeration e = getSongs(songs); e.hasMoreElements(); ){ SongInfo song=(SongInfo)e.nextElement(); out.print("