Đại Học Công Nghệ Thông Tin ĐH Quốc Gia Tp HCM ____________***********_____________ Báo cáo môn học Lập Trình Hệ Thống với Java Đề tài số 7: Tìm hiểu Lập trình phân tán trong Java (Nguồn Chương 5 cuốn Core Java™ 2 Volume II - Advanced Features, Seventh Edition) GVHD: Bùi Thanh Hiếu(Msc) Thành viên nhóm: Huỳnh Thái Bình Hoàng Minh Hải Huỳnh Xuân Tâm Phan Thanh Hưng 08520031 08520105 08520326 08520164
26/04/2011 Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011 Lời nói đầu Lập trình đối tượng phân tán là một trong những vấn đề nóng bỏng của công nghệ phần mền ngày nay. Java là ngôn ngữ đi tiên phong trong việc giải quyết vấn đề lập trình phân tán. Ngày nay nếu bạn không biết đến kỹ thuật lập trình này thì quả là một thiếu sót lớn. Từ .NET của Microsoft cho đến Java của Sun tất cả đều hướng đến môi trường hợp tác và tận dụng nguồn
tài nguyên phân tán trên mạng. Chương này sẽ giới thiệu với bạn khái niệm và cách cài đặt các đối tượng phân tán bằng kỹ thuật RMI trong Java. Nội dung chính: The Roles of Client and Server. Remote Method Invocations. Setup for Remote Method Invocation. Parameter Passing in Remote Methods. Server Object Activation. Java IDL and CORBA. Remote Method Calls with SOAP. Phân chia công việc trong nhóm:
Bạn Huỳnh Thái Bình phụ trách phần: The Roles of Client and Server. Remote Method Invocations Bạn Hoàng Minh Hải phụ trách phần: Setup for Remote Method Invocation Bạn Huỳnh Xuân Tâm phụ trách phần: Parameter Passing in Remote Methods Server Object Activation Bạn Phan Thanh Hưng phụ trách 2 phần cuối: Java IDL and CORBA Remote Method Calls with SOAP 1 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java Trường Đại Học
Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011 I/. The Roles of Client and Server(Vai trò của Client và Server): - Lấy ý tưởng là thu thập thông tin trên một máy tính khách hàng và gửi thông tin qua mạng cho máy chủ. Giả sử rằng một người sử dụng trên một máy tính cá nhân sẽ điền vào mẫu yêu cầu thông tin. Dữ liệu được gửi đến máy chủ của nhà cung cấp. Các máy chủ xử lý yêu cầu và gửi lại thông tin sản phẩm cho khách hàng. Figure 5-1. Transmitting
objects between client and server - Trong mô hình truyền thống client/server, khách hàng yêu cầu một định dạng truyền tải và gửi dữ liệu yêu cầu đến máy chủ. Các máy chủ phân tích yêu cầu định dạng và các định dạng phản ứng để truyền cho khách hàng. Khách hàng sau đó phân tích những phản ứng và hiển thị nó cho người dùng. - Nếu bạn thực hiện bằng tay, có một rắc rối lớn: Bạn phải thiết kế một định dạng truyền tải, và bạn phải viết code cho việc chuyển đổi giữa dữ liệu
và định dạng truyền. 2 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011 Note: Trong ví dụ này, chúng tôi giả định rằng khách hàng là một máy tính tương tác với một người sử dụng. Tuy nhiên, khách hàng đều có thể chạy một ứng dụng web và yêu cầu một dịch vụ từ một chương trình chạy trên máy tính khác. Có hai đối tượng giao tiếp, đối tượng khách hàng trong ứng dụng
web và các đối tượng máy chủ thực hiện các dịch vụ. Đây là một mô hình rất phổ biến trong thực tế. - Chúng tôi quan tâm vào mô hình truyền thống client/server bởi vì nó làm cho vai trò của các máy khách và máy chủ trực quan hơn. - Cơ chế mà các lập trình viên làm cho khách hàng một phương pháp gọi thường xuyên, mà không lo lắng về việc gửi dữ liệu qua mạng hay phân tích phản ứng.đối tượng đã thực hiện công việc đó không nằm trong cùng một máy ảo. Nó có thể không được
thực hiện trong các ngôn ngữ lập trình Java. - Giải pháp là cài đặt một proxy(sử uỷ quyền) cho các đối tượng server trên client. Proxy là một phương pháp phổ biến. Các proxy client liên lạc với server. - Lập trình viên của đối tượng máy chủ không muốn phiền phức với các giao tiếp khách hàng. Giải pháp là cài đặt một đối tượng proxy thứ hai trên máy chủ. Các máy chủ proxy giao tiếp với các proxy của khách hàng, và nó làm cho phương pháp này phổ biến. Figure 5-2. Remote
method call with proxies 3 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011 - Vậy làm thế nào để các proxy giao tiếp với nhau? -> Điều đó phụ thuộc vào công nghệ thực hiện. - Có ba sự lựa chọn phổ biến: RMI, Java Remote Method Invocation Technology hỗ trợ phương thức gọi phân phối giữa các đối tượng Java. CORBA, Common Object Request Broker Architecture hỗ
trợ phương thức gọi giữa các đối tượng của bất kỳ ngôn ngữ lập trình. CORBA sử dụng Internet Inter-ORB Protocol, hoặc IIOP, để giao tiếp giữa các đối tượng. SOAP, Simple Object Access Protocol cũng là ngôn ngữ lập trình trung gian. Tuy nhiên, SOAP sử dụng một định dạng truyền dẫn dựa trên XML. Note: Microsoft sử dụng COM. Trong quá khứ, Microsoft đặt COM là một đối thủ so với CORBA. Tuy nhiên, tại thời điểm này, Microsoft tập trung vào SOAP. - CORBA và SOAP hoàn
toàn là ngôn ngữ trung gian. Chương trình client và server có thể được viết bằng C, C + +, Java, hoặc ngôn ngữ khác. Bạn cung cấp một giao diện để xác định tín hiệu của các phương thức và các loại dữ liệu đối tượng của bạn có thể xử lý. Những mô tả được định dạng bằng một ngôn ngữ đặc biệt, được gọi là ngôn ngữ định nghĩa giao diện (IDL) cho CORBA và ngôn ngữ mô tả các dịch vụ Web (WSDL) cho SOAP. - Khá ít người tin rằng CORBA là mô hình đối tượng của tương lai. Thành
thật mà nói CORBA đã có ích trong việc triển khai các vấn đê phức tạp và các vấn đề tương thích. - SOAP có thể đơn giản, nhưng nó cũng có thể trở nên khá phức tạp, vì nó yêu cầu nhiều tính năng hơn mà CORBA đã có. Các giao thức XML có lợi thế là ngôn ngữ gần gũi với con người nên giúp ích cho việc gỡ rối. Nhìn chung, CORBA hiệu quả hơn, mặc dù SOAP là một phù hợp tốt hơn cho một kiến trúc web. - Nếu cả hai đối tượng giao tiếp được thực hiện trong code Java, thì
việc dùng CORBA và SOAP là không cần thiết. Sun đã phát triển một cơ chế đơn giản, đó là phương pháp triệu gọi phương thức từ xa-Remote Method Invocation (RMI), đặc biệt dùng cho giao tiếp giữa các ứng dụng Java. 4 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011 II./ Remote Method Invocations(Gọi phương thức từ xa): - Nếu bạn có quyền truy cập vào một đối tượng trên
một máy tính khác, bạn có thể gọi các phương thức của đối tượng từ xa. Tất nhiên, các tham số phương thức bằng cách nào đó phải được gửi đến các máy khác, máy chủ phải được thông báo để thực hiện các phương thức, và giá trị trả về phải được return trở lại. RMI xử lý việc này. - Ví dụ: client tìm kiếm thông tin sản phẩm có thể truy vấn một đối tượng trên máy chủ. Nó gọi một phương thức từ xa, tìm kiếm, trong đó có một tham số: một đối tượng khách hàng. Việc tìm thấy
trả về một đối tượng cho client: đối tượng của sản phẩm Figure 5-3. Invoking a remote method on a server object - Trong thuật ngữ RMI , các đối tượng của phương thức tạo ra lời gọi từ xa được gọi là client object. Các đối tượng từ xa được gọi là server object. Điều quan trọng là phải nhớ rằng thuật ngữ client/server chỉ áp dụng cho một lời gọi phương thức duy nhất. Các máy tính đang chạy code Java mà gọi phương thức từ xa là client và máy tính lưu trữ các đối
tượng mà thực hiện lời gọi là server. Điều này hoàn toàn làm cho vai trò được đảo ngược lại. Server của một lời gọi trước đó có thể trở thành client khi gọi một một đối tượng bằng phương thức từ xa ở trên máy tính khác. 5 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011 1/. Stubs and Parameter Marshalling: - Khi client muốn gọi một phương thức từ xa trên một đối
tượng từ xa, thì nó gọi 1 phương pháp thông thường trên một đối tượng proxy gọi là stub. Stub nằm trên máy client, không phải trên server. Ví dụ, trong giao thức RMI các đối tượng được mã hoá với cơ chế tuần tự. Quá trình mã hóa các thông số được gọi là tham số marshalling(parameter marshalling). Mục đích của tham số marshalling là chuyển đổi các tham số vào một định dạng thích hợp cho việc vận chuyển từ máy ảo với nhau. - Phương thức stub trên client xây dựng một
khối thông tin bao gồm: o Nhận dạng đối tượng từ xa sẽ được sử dụng; o Một mô tả của phương thức được gọi ; o Các tham số marshalled. - Phương thức stub sau đó gửi thông tin này tới server. Về phía server, một đối tượng thực hiện các hành động cho mỗi lời gọi phương thức từ xa: o Nó không có các thông số marshals. o Nó định vị đối tượng được gọi . o Nó gọi phương thức mong muốn. o Nó sẽ giữ và sắp đặt giá trị trả về hoặc ngoại lệ của cuộc gọi. o Nó sẽ gửi
một gói gồm các dữ liệu trả về marshalled tới stub trên client 6 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011 Figure 5-4. Parameter marshalling - Quá trình này rõ ràng là phức tạp, nhưng nó hoàn toàn tự động và minh bạch cho các lập trình viên. Hơn nữa, các nhà thiết kế của các đối tượng Java từ xa đã cố gắng để cung cấp cho các đối tượng từ xa cùng "look and
feel(xem và cảm thấy)" như các đối tượng nội tại. 2./ Dynamic Class Loading: - Khi truyền một đối tượng từ xa đến một chương trình khác, như là một tham số hay giá trị trả về của một phương thức từ xa, thì chương trình đó phải có các file class cho đối tượng đó. Ví dụ, hãy xem xét một phương thức với kiểu trả về là các sản phẩm. Tất nhiên, chương trình client cần các lớp Product.class để biên dịch. Nhưng bây giờ giả sử server khởi tạo và trả về một đối tượng sách,
và sách là một phân nhóm của sản phẩm. Các client có thể chưa bao giờ thấy class Book, và nó có thể đã không biết nơi để tìm file lớp Book.class - Do đó, một bộ nạp lớp đó sẽ được tải từ máy chủ. Quá trình này cũng tương tự như quá trình nạp lớp của các applet chạy trong trình duyệt. Bất cứ khi nào một chương trình tải mới mã từ một vị trí mạng, sẽ phát sinh vấn đề an ninh. 7 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java Trường Đại Học
Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011 Vì lý do đó, bạn cần sử dụng một chương trình quản lý bảo mật(security manager) trong các ứng dụng client RMI. Đây là một cơ chế an toàn để bảo vệ các chương trình từ virus trong mã stub. Đối với các ứng dụng chuyên ngành, các lập trình có thể thay thế bộ tải lớp của mình và quản lý an ninh, nhưng được cung cấp bởi hệ thống RMI là đủ cho sử dụng bình thường. III/. Setup for Remote Method Invocation(Cài đặt
cho phương pháp truyền dẫn dữ liệu từ xa): - Ngay cả khi chạy những ví dụ đơn giản nhất các đối tượng từ xa(remote object) yêu cầu nhiều hơn những thiết lập không chạy một chương trình độc lập hoặc applet. Bạn phải chạy các chương trình trên cả các máy tính máy chủ và máy khách. Các thông tin object cần thiết phải được tách vào vào phía giao diện máy khách và giao diện máy chủ phía triển khai. Ngoài ra, một cơ chế đặc biệt cho phép client tra cứu để xác định vị trí
các object trên máy chủ. - Để bắt đầu, chúng ta đi qua từng yêu cầu, sử dụng ví dụ đơn giản. Trong ví dụ đầu tiên của chúng ta tạo ra một vài đối tượng của một loại sản phẩm trên máy chủ. Sau đó chúng ta chạy một chương trình trên một máy tính client để xác định vị trí và truy vấn các đối tượng này. 1/. Interfaces and Implementations(Giao diện và Triển khai): - Chương trình client cần để thao tác các đối tượng server nhưng nó không thực sự copy chúng . Các đối
tượng tự cư trú trên máy chủ. Mã client vẫn phải biết những gì nó có thể làm với các đối tượng, khả năng của chúng được thể hiện trong một giao diện được chia sẻ giữa client và server và để cư trú đồng thời trên cả hai máy. interface Product // shared by client and server extends Remote { String getDescription() throws RemoteException; } - Cũng như trong ví dụ này tất cả các giao diện cho các remote object phải mở rộng giao diện từ xa được xác định
trong gói java.rmi. Tất cả các phương pháp trong các giao diện cũng phải biểu thị một Remote Exception. Lý do cho việc khai báo là cuộc gọi phương thức từ xa vốn ít tin cậy hơn cuộc gọi địa phương, luôn luôn có thể có một cuộc gọi từ xa sẽ thất bại. Ví dụ, máy chủ hoặc kết nối mạng có thể tạm thời không có hoặc có vấn đề mạng. Code máy client của bạn phải được chuẩn bị để đối phó với những khả năng này. Đối với những lý do này. Ngôn ngữ lập trình Java buộc bạn phải theo
kịp Remote Exception với tất cả các 8 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011 cuộc gọi phương thức từ xa và để xác định các hành động thích hợp để có khi cuộc gọi không thành công. Các khách hàng truy cập các đối tượng máy chủ thông qua stub để thực hiện giao diện này. Product p = . . .; // see below how the client gets a stub reference String d =
p.getDescription(); System.out.println(d); - Trong phần tiếp theo, bạn sẽ thấy làm thế nào client có thể có được một tham chiếu đến loại đối tượng từ xa. - Tiếp theo, ở phía máy chủ, bạn phải thực hiện các lớp mà thực sự thực hiện các phương pháp quảng cáo trong giao diện từ xa. public class ProductImpl // server extends UnicastRemoteObject implements Product { public ProductImpl(String d) throws RemoteException { descr = d; }
public String getDescription() throws RemoteException { return "I am a " + descr + ". Buy me!"; } private String descr; } NOTE constructor ProductImpl được khai báo để dịch chuyển RemoteException vì UnicastRemoteObject có thể dịch chuyển ngoại lệ nếu nó không thể kết nối với dịch vụ mạng theo dõi các đối tượng máy chủ - Lớp này có một phương pháp duy nhất, geTDescription ,có thể được gọi từ các khách hàng từ xa 9 Lập Trình Hệ Thống
Với Java – Tìm hiểu lập trình phân tán trong Java Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011 - Bạn có thể nói rằng class là một máy chủ cho các phương pháp điều khiển từ xa bởi vì nó mở rộng UnicastRemoteObject, mà là một lớp Java nền tảng cho các đối tượng truy cập từ xa. NOTE Lớp ProductImpl không phải là một lớp máy chủ điển hình bởi vì nó làm việc quá ít. Thông thường, bạn chỉ muốn có máy chủ làm một số công việc nặng mà một
client không thể thực hiện. Chúng tôi chỉ sử dụng các ví dụ sản phẩm để hướng dẫn bạn qua các cơ chế gọi các phương thức từ xa. - Các class server thường mở rộng lớp RemoteServer từ gói java.rmi.server. nhưng RemoteServer là một lớp trừu tượng mà chỉ xác định các cơ chế cơ bản trong giao tiếp giữa máy chủ và các đối tượng khai từ xa Lớp UnicastRemoteObject mà đi kèm với RMI mở rộng lớp trừu tượng và là RemoteServer bạn có thể sử dụng nó mà không cần viết bất kỳ mã nào
."path of least resistance "cho một lớp máy chủ là có nguồn gốc từ UnicastRemoteObject, và tất cả các lớp máy chủ trong chương này làm như vậy. Hình 5-5 cho thấy mối quan hệ thừa kế giữa các lớp này. 10 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011 - Một đối tượng UnicastRemoteObject nằm trên máy chủ. Nó còn chạy được khi một dịch vụ được yêu cầu và phải được truy
cập thông qua giao thức TCP / IP. Đây là lớp mà chúng tôi mở rộng cho tất cả các lớp máy chủ trong cuốn sách này và là lớp máy chủ chỉ có trong phiên bản hiện tại của gói RMI. Sun(mặt trời) hoặc bên thứ ba nhà cung cấp có thể, trong tương lai, thiết kế các lớp khác để sử dụng bởi các máy chủ cho RMI. NOTE Thỉnh thoảng, bạn có thể không muốn có một lớp máy chủ mở rộng lớp UnicastRemoteObject, có lẽ bởi vì nó đã được mở rộng một lớp khác. Trong tình hình đó, bạn cần
phải tự khởi tạo các đối tượng máy chủ và truyền cho phương thức exportObject tĩnh. Thay vì mở rộng UnicastRemoteObject,ta gọi: UnicastRemoteObject.exportObject(this, 0); Trong xây dựng của các đối tượng máy chủ. Tham số thứ hai là 0 để chỉ ra rằng bất kỳ cổng thích hợp có thể được sử dụng để lắng nghe các kết nối client - Khi bạn sử dụng RMI (hoặc bất kỳ cơ chế đối tượng phân tán, cho từng vấn đề), bạn sẽ cần phải nắm vững một chút bối rối tập các lớp. Trong chương
này, chúng tôi sử dụng một quy ước đặt tên thống nhất cho tất cả các ví dụ của chúng tôi mà chúng tôi hy vọng làm cho nó dễ dàng hơn để nhận ra mục đích của từng loại(xem Bảng 5-1) 11 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011 2/. Stub Class Generation: - Theo JDK 5.0, tất cả các lớp stub được tạo ra tự động, sử dụng cơ chế proxy thảo luận trong Tập 1,
chương 6. Tuy nhiên, trước khi JDK 5.0, bạn phải tự tạo ra khai với công cụ rmic, như trong ví dụ sau đây rmic -v1.2 ProductImpl -Điều này gọi đến các công cụ rmic tạo ra một lớp tập tin ProductImpl_Stub.class - Nếu bạn sử dụng JDK 1.1 hãy gọi: rmic -v1.1 ProductImpl - Hai tập tin được tạo ra: các tập tin stubs và lớp một tập tin thứ hai tên là ProductImpl_Skel.class. NOTE Hãy nhớ đến đầu tiên biên dịch tập tin nguồn với javac trước khi chạy
rmic. Nếu bạn đang tạo ra khai cho một lớp trong một gói, bạn phải cung cấp cho rmic tên gói đầy đủ. 3/. Locating Server Objects: - Để truy cập một đối tượng từ xa mà tồn tại trên máy chủ, khách hàng cần có một đối tượng stub địa phương, Làm thế nào có thể yêu cầu client như một stub. Phương pháp phổ biến nhất là để gọi một phương thức từ xa của một đối tượng server và nhận được một đối tượng stub như là một giá trị trả về. - Tuy nhiên,có một vấn đề "con gà và
quả trứng” ở đây. Các đối tượng máy chủ đầu tiên đã được đặt một cách khác. The Sun RMI thư viện cung cấp dịch vụ đăng ký khởi động để định vị các đối tượng máy chủ đầu tiên, Một chương trình máy chủ đăng ký các đối tượng với dịch vụ đăng ký khởi động, và client truy khai cho các đối tượng. Bạn đăng ký một đối tượng máy chủ bằng cách cho cơ quan đăng ký khởi động dịch vụ một tham chiếu đến các đối tượng và tên một. Tên này là một chuỗi được (hy vọng) độc đáo // server
ProductImpl p1 = new ProductImpl("Blackwell Toaster"); Context namingContext = new InitialContext(); namingContext.bind("rmi:toaster", p1); 12 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011 - Mã khách hàng nhận được một stub đối tượng để truy cập máy chủ bằng cách chỉ định tên máy chủ và tên các đối tượng theo cách sau: // client Product p = (Product)
namingContext.lookup("rmi://yourserver.com/toaster"); - RMI URL bắt đầu với rmi: / / và được theo sau bởi một máy chủ, một số cổng tùy chọn, giảm khác, và tên của các đối tượng từ xa. Một ví dụ khác là: rmi://localhost:99/central_warehouse - Mặc định thì server là localhost và port là 1099. NOTE Bởi vì nó là rất khó khăn để giữ các tên duy nhất trong một đăng ký toàn cầu, bạn không nên sử dụng kỹ thuật này là phương pháp chung để định vị đối tượng trên
máy chủ. Thay vào đó, cần có tương đối ít đối tượng máy chủ tên đăng ký với dịch vụ khởi động. đối tượng có thể xác định vị trí các đối tượng khác cho bạn. Trong ví dụ của chúng tôi, chúng tôi tạm thời hành vi vi phạm quy tắc này và đăng ký các đối tượng tương đối nhỏ để cho bạn thấy cơ chế đăng ký, định vị đối tượng. - Vì lý do an ninh, ứng dụng có thể mở ra ràng buộc, hoặc đăng ký tài liệu tham khảo đối tượng rebind chỉ khi nó chạy trên máy chủ giống như đăng ký. Điều
này ngăn cản các client thù địch từ thay đổi thông tin đăng ký. Tuy nhiên, bất kỳ client cũng có thể tra cứu các đối tượng. Các dịch vụ RMI đặt tên là tích hợp vào trong đặt tên Java và mục thông tin (JNDI) dịch vụ. Trong JDK 1.3 và dưới đây, bạn sử dụng một dịch vụ RMI đặt tên độc, như thế này: Naming.bind("toaster", p1); // on the server Product p = (Product) Naming.lookup("rmi://yourserver.com/toaster"); TIP Nếu bạn so sánh các máy chủ của chúng tôi với các
ví dụ máy chủ trong tài liệu hướng dẫn Sun, bạn sẽ lưu ý rằng chúng tôi không cài đặt một trình quản lý bảo mật trong máy chủ. Trái ngược với các báo cáo trong hướng dẫn này, một quản lý an ninh là không cần thiết cho các máy chủ RMI. Bạn cần một quản lý an ninh, nếu client gửi đến các đối tượng máy chủ thuộc về các lớp mà máy chủ không biết. Tuy nhiên, trong dịch vụ của chúng tôi, client chỉ gửi các thông số String. Nói chung, nó có vẻ khôn ngoan để hạn chế nạp lớp động
trên các máy chủ. 13 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011 Example 5-1. ProductServer.java 1. import java.rmi.*; 2. import java.rmi.server.*; 3. import javax.naming.*; 4. 5. /** 6. This server program instantiates two remote objects, 7. registers them with the naming service, and waits for 8. clients to invoke methods on the
remote objects. 9. */ 10. public class ProductServer 11. { 12. public static void main(String args[]) 13. { 14. try 15. { 16. System.out.println("Constructing server implementations..."); 17. 18. ProductImpl p1 = new ProductImpl("Blackwell Toaster"); 19. ProductImpl p2 = new ProductImpl("ZapXpress Microwave Oven"); 20. 21. System.out.println("Binding server implementations to registry...");
22. Context namingContext = new InitialContext(); 23. namingContext.bind("rmi:toaster", p1); 24. namingContext.bind("rmi:microwave", p2); 25. System.out.println("Waiting for invocations from clients..."); 26. } 27. catch (Exception e) 28. { 29. e.printStackTrace(); 30. } 31. } 32. } Example 5-2. ProductImpl.java 1. import java.rmi.*; 2. import java.rmi.server.*; 3. 4. /** 5.
This is the implementation class for the remote product 14 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. objects. */ public class ProductImpl extends UnicastRemoteObject implements
Product { /** Constructs a product implementation @param n the product name */ public ProductImpl(String n) throws RemoteException { name = n; } public String getDescription() throws RemoteException { return "I am a " + name + ". Buy me!"; } private String name; } Example 5-3. Product.java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. import java.rmi.*; /** The
interface for remote product objects. */ public interface Product extends Remote { /** Gets the description of this product. @return the product description */ String getDescription() throws RemoteException; } 4/. Starting the Server: - Chương trình máy chủ của chúng tôi là không hoàn toàn sẵn sàng để chạy được. Bởi vì nó sử dụng các chương trình khởi động RMI Registry, dịch vụ đó phải có sẵn. Để bắt đầu đăng ký RMI theo UNIX, thực hiện các
tuyên bố rmiregistry & 15 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011 - Nếu là Windows thì gọi: start rmiregistry - Giờ thì bạn có thể khởi động Server. Nếu là Unix thì chạy lệnh: java ProductServer & - Nếu là Windows thì chạy lệnh: start java ProductServer - Nếu bạn chạy chương trình theo cách sau: java ProductServer
thì chương trình sẽ không bao giờ thoát ra bình thường.Điều này có vẻ kỳ lạ sau khi tất cả, chương trình chỉ tạo ra hai đối tượng và đăng ký chúng.Trên thực tế,các chức năng chính không xuất cảnh ngay lập tức sau khi đăng ký,như bạn mong đợi. Tuy nhiên,khi bạn tạo 1 đối tượng của một lớp mở rộng UnicastRemoteObject, một chủ đề riêng biệt để duy trì chương trình còn sống vô thời hạn được bắt đầu. Vì vậy, chương trình tồn tại xung quanh để cho phép khách hàng để kết nối với nó.
TIP Các phiên bản Windows của JDK bao gồm một lệnh, javaw, mà bắt đầu các phiên dịch bytecode là một quá trình Windows riêng biệt và giữ nó chạy. Một số nguồn khuyên bạn nên sử dụng javaw, không phải start java, để chạy một phiên Java trong nền trong Windows cho RMI. Làm như vậy không phải là một ý tưởng tốt, vì hai lý do. Windows không có công cụ để giết một quá trình nền javaw không hiển thị trong danh sách công việc. Nó chỉ ra rằng bạn cần phải giết và khởi động
lại dịch vụ đăng ký khởi động khi bạn thay đổi STUB của một lớp đăng ký. Để giết một quá trình mà bạn bắt đầu với lệnh bắt đầu, tất cả các bạn phải làm là nhấp chuột vào cửa sổ và nhấn Ctrl + C Còn có một lý do quan trọng để sử dụng lệnh start. Khi bạn chạy một quá trình máy chủ bằng cách sử dụng javaw, tin nhắn gửi tới đầu ra hoặc lỗi được loại bỏ. Đặc biệt, họ không được hiển thị ở bất cứ đâu. Nếu bạn muốn xem kết quả hoặc thông báo lỗi, sử dụng start. Sau đó, thông
báo lỗi ít nhất là hiển thị trên giao diện điều khiển. Và tin tưởng chúng TÔI, bạn sẽ muốn nhìn thấy những tin nhắn này. Rất nhiều những thứ có thể đi sai khi bạn thử nghiệm với RMI. Các lỗi phổ biến nhất có lẽ là bạn quên chạy rmic. Sau đó, máy chủ than phiền về việc thiếu STUB . Nếu bạn sử dụng javaw, bạn sẽ không thấy thông báo lỗi, và bạn sẽ gãi đầu của bạn tự hỏi tại sao các CLIENT không có thể tìm thấy các đối tượng máy chủ. 16 Lập Trình Hệ Thống Với Java –
Tìm hiểu lập trình phân tán trong Java Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011 5/. Listing Remote Objects: - Trước khi viết chương trình client, hãy xác minh rằng chúng ta đã thành công trong việc đăng ký các đối tượng từ xa. Ta gọi: NamingEnumeration e = namingContext.list("rmi:"); để có được một điều tra của tất cả các đối tượng máy chủ với một rmi: URL. Việc liệt kê sản lượng các đối tượng của loại
NameClassPair, một lớp học bổ trợ có chứa cả tên của đối tượng bị ràng buộc và tên của các lớp . Chúng tôi chỉ quan tâm đến những cái tên: while (e.hasMore()) System.out.println(e.next().getName()); - Ví dụ 5-4 chứa chương trình đầy đủ. Output sẽ là: toaster microwave Example 5-4. ShowBindings.java 1. import java.rmi.*; 2. import java.rmi.server.*; 3. import javax.naming.*; 4. 5. /** 6. This programs shows all RMI bindings. 7.
*/ 8. public class ShowBindings 9. { 10. public static void main(String[] args) 11. { 12. try 13. { 14. Context namingContext = new InitialContext(); 15. NamingEnumeration e = namingContext.list("rmi:"); 16. while (e.hasMore()) 17. System.out.println(e.next().getName()); 18. } 19. catch (Exception e) 20. { 21. e.printStackTrace(); 22. } 23. } 24. }
6/. The Client Side: 17 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011 - Bây giờ, chúng ta có thể viết các chương trình CLIENT có yêu cầu từng đối tượng sản phẩm mới được đăng ký để in mô tả của nó. chương trình CLIENT có sử dụng RMI nên cài đặt một trình quản lý an ninh để kiểm soát các hoạt động của các STUB động nạp. RMISecurityManager là như một người quản lý bảo
mật. Bạn cài đặt nó với chỉ dẫn sau: System.setSecurityManager(new RMISecurityManager()); NOTE Nếu tất cả các lớp (bao gồm cả stub ) có sẵn tại địa phương, sau đó bạn không thực sự cần một người quản lý bảo mật. Nếu bạn biết tất cả các tập tin lớp của chương trình của bạn tại thời gian triển khai, bạn có thể triển khai chúng tất cả các địa phương. Tuy nhiên, nó thường xảy ra rằng chương trình tiến hóa máy chủ và các lớp mới được thêm vào theo thời gian. Sau
đó, bạn được hưởng lợi từ việc nạp lớp năng động. Bất cứ lúc nào bạn mã tải từ một nguồn khác, bạn cần một người quản lý bảo mật. NOTE Applet đã có một người quản lý bảo mật mà có thể kiểm soát tải của các lớp stub. Khi sử dụng RMI từ applet, bạn không cài đặt một người quản lý bảo mật. Example 5-5. ProductClient.java [View full width] 1. import java.rmi.*; 2. import java.rmi.server.*; 3. import javax.naming.*; 4. 5. /** 6. This program
demonstrates how to call a remote method 7. on two objects that are located through the naming service. 8. */ 9. public class ProductClient 10. { 11. public static void main(String[] args) 12. { 13. System.setProperty("java.security.policy", "client.policy"); 14. System.setSecurityManager(new RMISecurityManager()); 15. String url = "rmi://localhost/"; 18 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong
Java Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011 16. // change to "rmi://yourserver.com/" when server runs on remote machine yourserver.com 17. try 18. { 19. Context namingContext = new InitialContext(); 20. Product c1 = (Product) namingContext.lookup(url + "toaster"); 21. Product c2 = (Product) namingContext.lookup(url + "microwave"); 22. 23.
System.out.println(c1.getDescription()); 24. System.out.println(c2.getDescription()); 25. } 26. catch (Exception e) 27. { 28. e.printStackTrace(); 29. } 30. } 31. } 7/. Running the Client: - Theo mặc định, RMISecurityManager những hạn chế tất cả các mã trong chương trình từ việc thiết lập kết nối mạng. Tuy nhiên, chương trình cần để làm cho các kết nối mạng. Để đạt được đăng ký RMI, và để liên hệ với các đối
tượng máy chủ. - Một khi các chương trình client được triển khai, nó cũng cần sự cho phép để tải các lớp stub của nó. Chúng tôi quyết vấn đề này sau khi chúng tôi thảo luận triển khai. - Để cho phép các client để kết nối đến cơ quan đăng ký RMI và đối tượng máy chủ, bạn cung cấp một tập tin chính sách. Chúng tôi thảo luận về các tập tin chính sách cụ thể hơn trong chương 9. Để bây giờ, chỉ cần sử dụng và sửa đổi các mẫu mà chúng tôi cung cấp. Dưới đây là một tập
tin chính sách cho phép một ứng dụng để thực hiện bất kỳ kết nối mạng vào một cổng với số cổng ít nhất là 1024. (Cổng RMI là 1099 theo mặc định, và các đối tượng máy chủ cũng sử dụng cổng ≥ 1024.) grant { permission java.net.SocketPermission "*:1024-65535", "connect"; 19 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java |