3. CHƯƠNG 3: LẬP TRÌNH PHÂN TÁN VỚI CORBA
1.9. XÂY DỰNG ỨNG DỤNG CORBA TRONG MÔI TRƯỜNG JAVA
Ta thực hiện viết một chương trình Hello World đơn giản. Chương trình CORBA trên máy Client sẽ gọi đối tượng trên máy Server. Đối tượng trên máy server sẽ trả về chuỗi mang lời chào “Hello World!!”.
Công việc phía Server:
• Xây dựng đặc tả Hello.idl
• Xây dựng đối tượng Hello bằng idlj và ngôn ngữ Java. • Khởi động dịch vụ đăng ký tnameserv.exe
• Viết chương trình cài đặt đối tượng Hello lên máy chủ.
Công việc phía Client:
• Xây dựng chương trình gọi đối tượng Hello của máy chủ.
3.1.5. Các công việc phía Server:
Bước 1: Chúng ta cần một đối tượng Hello. Đối tượng này cung cấp phương thức
sayHello(). Đặc tả đối tượng bằng ngôn ngữ CORBA IDL được diễn đạt như sau:
interface Hello {
string sayHello(); };
Bước 2: Xây dựng đối tượng Hello bằng ngôn ngữ Java
Với nội dung của tập tin Hello.idl, ta sử dụng chương trình idlj.exe để chuyển đặc tả sang ngôn ngữ Java. Đánh lệnh biên dịch như sau:
idlj -fall Hello.idl
Kết quả ta thu được các tập tin sau:
HelloOperations.java Tập tin chuyển đặc tả IDL thành đặc tả interface của Java
Hello.java Tập tin chuyển lớp giao tiếp đối tượng kiểu Java
thành lớp giao tiếp đối tượng đặc thù trong CORBA.
HelloHelper.java
Cung cấp một số phương thức tiện ích để xử lý đối tượng Hello (như phương thức narow() dùng để ép kiểu).
HelloHolder.java
Chịu trách nhiệm xử lý việc chuyển đối tượng Hello qua lại giữa trình trung gian ORB trên máy khách và máy chủ.
_HelloStub.java
Chịu trách nhiệm xử lý việc chuyển đối tượng Hello qua lại giữa trình trung gian ORB trên máy khách và máy chủ.
Muốn cài đặt đối tượng CORBA ta quan tâm đến lớp HelloPOA. Đối tượng CORBA thật sự của lớp Hello sẽ được cài đặt ở bước kế tiếp.
Bước 3: Cài đặt đối tượng CORBA Hello
//HelloImpl.java
import org.omg.CORBA.*;
class HelloImpl extends HelloPOA {
private ORB orb;
public void setORB(ORB orb_val) { orb = orb_val;
}
public String sayHello() {
return "Hello World!!";
}
}
Lớp HelloPOA nguyên thủy kế thừa từ lớp CORBA.Object, cho nên lớp HelloImpl được kế thừa từ HelloPOA cũng là một đối tượng CORBA chính thống.
Các lớp Hello.class, HelloOperations.class là những lớp trung gian hỗ trợ cho lời gọi của trình môi giới ORB đến đối tượng CORBA.
Bước 4: Khởi động trình đăng ký đối tượng CORBA trên Server, chương trình này là tnameserv.exe. Mặc định dịch vụ này chạy trên cổng 900. Ta có thể thay đổi cổng cho nó. Ví dụ ta muốn chạy tnameserv trên cổng 1020, dùng lệnh:
tnameserv -ORBInitialPort 1020
Thực hiện khởi động tnamserv như sau:
Xây dựng chương trình cài đặt và đăng ký đối tượng CORBA HelloImpl tại máy chủ: // HelloServer.java import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; import org.omg.PortableServer.*; import org.omg.PortableServer.POA; import java.util.Properties; class HelloServer {
public static void main(String args[]) { try{
//khởi động trình môi giới đối tượng ORB
ORB orb = ORB.init(args, null);
POA rootpoa = POAHelper.narrow(orb.resolve_initial_references("RootPOA")); rootpoa.the_POAManager().activate();
// Tạo đối tượng phục vụ để đăng kí với ORB
HelloImpl helloImpl = new HelloImpl(); helloImpl.setORB(orb);
// Lấy tham chiếu đến dịch vụ đăng ký tnameserv
org.omg.CORBA.Object ref = rootpoa.servant_to_reference(helloImpl); Hello href = HelloHelper.narrow(ref);
// Lấy về naming context gốc
org.omg.CORBA.Object objRef =
orb.resolve_initial_references("NameService");
NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
// Đăng kí đối tượng
String name = "Hello";
NameComponent path[] = ncRef.to_name( name ); ncRef.rebind(path, href);
System.out.println("HelloServer ready and waiting ..."); // wait for invocations from clients
orb.run(); } catch (Exception e) { System.err.println("ERROR: " + e); e.printStackTrace(System.out); } System.out.println("HelloServer Exiting ..."); } } Chạy trình chủ:
3.1.6. Công việc phía Client:
Cài đặt trình khách như sau:
// HelloClient.java
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*;
class HelloClient { static Hello helloImpl;
public static void main(String args[]) { try{
// Khởi tạo ORB
ORB orb = ORB.init(args, null);
// Lấy về naming context gốc
org.omg.CORBA.Object objRef =
orb.resolve_initial_references("NameService");
NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
// Truy xuất đối tượng tìm được
String name = "Hello";
helloImpl = HelloHelper.narrow(ncRef.resolve_str(name));
System.out.println("Obtained a handle on server object: " + helloImpl); System.out.println(helloImpl.sayHello()); } catch (Exception e) { System.out.println("ERROR : " + e) ; e.printStackTrace(System.out); } } } Chạy chương trình khách:
Các file cần thiết cho chương trình khách là: _HelloStub.class, HelloClient.class, HelloHelper.class, HelloOperations.class, _HelloStub.class
3.1.7. Các cách khởi động trình môi giới ORB:
Ở ví dụ Hello nói trên chúng ta đã khởi động trình môi giới ở hai phía khách chủ bằng cách gọi lệnh:
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ừ các 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.
Trong trường hợp ta không dùng các giá trị mặc định của ORB thì ta có thể khởi tạo các đối số cho ORB từ dòng lệnh như sau:
Trên máy chủ:
Ta có thể chỉ định các tùy chọn để ORB khởi động ngay trong mã lệnh như sau:
//Setup.java
import org.omg.CORBA.*; import org.util.Properties; class Client {
public static void main(String args[]) { Properties props = new Properties();
props.put(“org.omg.CORBA.ORBInitialPort”,”1050”); ORB orb = ORB.init(args,props);
… } }
Trong trường hợp ta chỉ định cả hai tùy chọn là vừa từ tham số dòng lệnh và vừa từ mã lệnh thì ORB sẽ ưu tiên lấy các tùy chọn do mã lệnh thiết lập.