Learning Community

ผลงานวิทยานิพนธ์
ของคุณ พนิต เวชศิลป์
ภาควิชาวิศวกรรมคอมพิวเตอร์
สถาบันเทคโนโลยีพระจอมเกล้าเจ้าคุณทหารลาดกระบัง

ปรับแก้ไขโดยนาย รุ่งโรจน์ โรจนโพธิ์ ( ธันวาคม 2548 )




Learning Community
• Home
• Jini Beginning
- บทเรียนที่ 1
- บทเรียนที่ 2
- บทเรียนที่ 3
- บทเรียนที่ 4
- บทเรียนที่ 5
- บทเรียนที่ 6
- บทเรียนที่ 7
- บทเรียนที่ 8
- บทเรียนที่ 9


บทที่ 3

Java RMI เบื้องต้น



Java RMI ( Remote Method Invocation ) คือระบบวัตถุแบบกระจาย ( Distributed Object System ) เบื้องต้น ก่อนจะพัฒนาไปสู่ง Jini Network ตามแนวทางปรัชญาของ Linda Systems ที่วางไว้ตั้งแต่ปี 1982 ซึ่งพัฒนาโดยบริษัท Sun Microsystems คำว่า ออบเจ็กต์แบบกระจายนั้น หมายถึงว่า ออบเจ็กต์ที่ทำงานอยู่เป็นระบบหนึ่งนั้น สามารถกระจายอยู่ตามที่ต่าง ๆ บนเครือข่าย ( บน Java Virtual Machine ในที่ต่าง ๆ ในระบบเครือข่าย ) ซึ่งออบเจ็กต์ที่ถูกสร้างที่อยู่ต่าง Virtual Machine กัน( แม้เครื่องเดียวกันก็ได้ ) สามารถเรียกใช้ Method ระหว่างกันได้โดยผ่านทางกระบวนการของ Java RMI ซึ่งในฝั่งผู้เรียกใช้ออบเจ็กต์ นั้นจะเรียกใช้ Object นั้น ได้เหมือนกับว่า Object นั้นอยู่ใน Address Space เดียวกัน ซึ่งมีลักษณะที่คล้ายกับระบบออบเจ็กต์แบบกระจาย แบบอื่น ๆ เช่น CORBA หรือ RPCs แต่แตกต่างกันที่ Java RMI นั้นถูกพัฒนามาให้ใช้กับ ภาษาจาวาเท่านั้น แต่ CORBA หรือ RPCs นั้น สามารถใช้กับภาษาใด ๆ ก็ได้


3.1 ข้อแตกต่างระหว่าง Java RMI กับ CORBA

  1. CORBA เป็นมาตรฐานที่ไม่ขึ้นอยู่กับภาษาใด ๆ ทำงานได้กับภาษาเชิงออบเจ็กต์ ได้เกือบจะทุกภาษา
  2. CORBA มีกระบวนการต่าง ๆ อีกหลายอย่างที่เป็นมาตรฐาน( เช่น TP Monitor ) ซึ่งไม่มีใน Java RMI
  3. ไม่มีการพูดถึง Object Request Broker ใน Java RMI แต่ ในปัจจุบัน Java RMI ได้ถูกพัฒนาเพื่อเชื่อมต่อกับกับมาตรฐานของ CORBA ผ่าน IIOP ( Internet Inter-ORB Protocol ) หรือเรียกชื่อใหม่ว่า RMI/IIOP ( RMI Over IIOP )

3.2 สถาปัตยกรรมของ Java RMI


            การออกแบบ Java RMI นั้นทำขึ้นโดยมีเป้าหมายที่ว่าเพื่อจะสร้างระบบ ออบเจ็กต์แบบกระจายที่สามารถเข้ากันได้กับภาษาจาวา โดยที่ยังคงวิธีการเหมือนกับการเรียกใช้ Local Object ซึ่ง Java RMI ก็สามารถทำได้เป็นอย่างดี โดยส่วนประกอบที่เป็นพื้นฐานของสถาปัตยกรรมของ Java RMI มีดังต่อไปนี้

3.2.1 Interface : หัวใจหลักของ Java RMI


            สถาปัตยกรรมของ Java RMI มีหลักการสำคัญอยู่ 1 อย่างก็คือ การสร้างส่วนอธิบายวิธีการปฏิบัติการของออบเจ็กต์ ( Object Operation Definition ) หรือสามารถเรียกอีกอย่างได้ว่า Method Definition ของออบเจ็กต์ และการสร้างวิธีการปฏิบัติการของออบเจ็กต์ ( Object Operation Implementation ) ซึ่งส่วนที่ใช้อธิบายวิธีการปฏิบัติการของออบเจ็กต์ เราเรียกว่า Interface นั่นเอง ซึ่งทั้งสองส่วนนี้สามารถทำงานแยกกันในต่าง Virtual Machine ได้ ซึ่งหลักการนี้เข้ากันได้ดีกับหลักการของ ระบบออบเจ็กต์แบบกระจาย คือ ฝัง Client สามารถเรียกใช้ Method ผ่าน Interface ส่วน Server ก็มุ่งไปที่การให้บริการออบเจ็กต์

            ซึ่งการสร้างส่วนที่อธิบาย Operation ของออบเจ็กต์นั้น ในการเขียนโปรแกรมภาษาจาวาใช้ Interface ของภาษาจาวาในการสร้าง ส่วนการสร้าง ส่วนปฏิบัติการณ์ของออบเจ็กต์ ( Remote Service ) นั้น ใช้คลาสของจาวาในการสร้าง ดังนั้นหลักการสำคัญของ Java RMI ที่จะต้องรู้ก็คือ “ Interface อธิบายวิธีปฏิบัติการของออบเจ็กต์ ส่วน คลาสอธิบายการสร้างและการทำงานของออบเจ็กต์ โดย Client รู้จักเพียง Interface ส่วน Server ทำงานกับ คลาส”





รูปที่ 3-1 ระบบ Interface และอิมพลีเมนเทชัน


            ส่วนของ โค้ดที่เอ็กซิคิวต์ได้นั้น จะไม่มีอยู่ในส่วนของ Interface แต่ Java RMI จะรองรับ 2 คลาส ซึ่งสร้างจาก Interface เดียวกันโดย คลาสแรกทำหน้าที่เป็น Service Implemantation ในฝั่ง Server ส่วนคลาสที่สองทำหน้าที่เป็น Service Proxy สำหรับการ Remote Service จาก Client ดังที่แสดงในรูปต่อไปนี้





รูปที่ 3-2 การคุยกันระหว่าง Service Proxy และ Service Implemantation


            โปรแกรม Client จะเรียกใช้ Method จาก Service Proxy จากนั้น Java RMI จะทำการส่งคำร้องขอ ไปยัง Service ที่ฝั่ง Server ผ่าน Service Implemantation โดยฝัง Server จะทำการประมวลผลและถ้าหากมีผลลัพธ์ ผลลัพธ์นั้นก็จะถูกส่งกลับไปให้กับ Service Proxy และส่งคืนให้กับโปรแกรม Client ที่เรียกใช้ Method นั้น


3.2.2 ชั้นของสถาปัตยกรรมของ Java RMI


            เมื่อเข้าใจหลักการทำงานของ Java RMI ในภาพรวมแล้วก็ลองมาดูเบื้องหลังในส่วนที่อธิบายการทำงานของ Java RMI ว่าทำอย่างไร ถึงจะทำเช่นที่กล่าวมาในข้างต้นได้

            การทำงานของ Java RMI นั้น ถูกสร้างขึ้นมาจาก 3 Abstract Layer เลเยอร์ส่วนแรกคือ Stub & Skeleton Layer ส่วนที่สองคือ Remote Referance Layer ซึ่งอธิบายการเชื่อมต่อของ Java RMI รวมทั้งยังทำหน้าที่ในการดาวน์โหลด Java Byte Code ของ Class หรือ Object ที่ถูกอ้างถึง เพื่อมาประมวลผลทั้งฝัง Client และ Server ทำให้ทุกวันนี้ มีเพียง Java RMI เท่านั้น ที่ได้ชื่อว่า Object Network อย่างแท้จริง และส่วนที่ 3 คือ Transport Layer ซึ่งสร้างการเชื่อมต่อระหว่าง Java Virtual Machine ด้วย TCP/IP ซึ่งเลเยอร์ที่เราจะพิจารณาเพื่อความเข้าใจในโครงการนี้ เราจะสนใจเฉพาะแค่ Stub & Skeleton Layer เท่านั้น



รูปที่ 3-3 เลเยอร์ของสถาปัตยกรรมของ Java RMI


3.2.3 Stub & Skeleton Layer


การทำงานของ Layer นี้จะเป็นกระบวนการที่ผู้พัฒนาไม่จำเป็นต้องมาเกี่ยวข้อง ซึ่งทำหน้าที่รับการเรียกใช้ Method มาจาก Client และส่งการเรียกนี้ ( Remote Service ) ไปยังฝั่ง Server

ใน Layer นี้ Java RMI ได้ใช้ดีไซน์แพทเทิร์นคือ พรอกซี่แพทเทิร์นซึ่งในพรอกซี่แพทเทิร์นนั้น ออบเจ็กต์ที่อยู่ในสิ่งแวดล้อมของระบบหนึ่งสามารถถูกแสดงแทนในอีกระบบหนึ่งด้วยออบเจ็กต์ อีกออบเจ็กต์ หนึ่งที่เรียกว่าพรอกซี่ดังคลาสไดอะแกรมด้านล่างนี้



รูปที่ 3-4 ดีไซน์แพทเทิร์นแบบพรอกซี่


              Class ของ Stub และ Skeleton ถูกสร้างขึ้นใน Java RMI โดยสร้างจาก Base Class ที่ทำหน้าที่เป็น Remote Service ซึ่งวิธีการสร้างนั้นจะกล่าวถึงอีกทีในบทนี้

            Stub Class ทำหน้าที่เป็น Service Proxy และ Object ที่สร้างเป็น Remote Service ทำหน้าที่เป็น Real Subject ส่วน Skeleton Class ทำหน้าที่เป็น Service Implemantation จะอ่านค่า Parameter ที่เรียกใช้ Method นั้น แล้วทำการเรียกต่อไปยัง Service Object แล้วรอรับค่าที่ส่งกลับมา จากนั้นจึงจะส่งค่านั้นกลับไปยัง Stub Class

            ตั้งแต่ Java 2 Platform, Standard Edition ( J2SE 1.2 ) ทางบริษัท Sun Microsystems ได้มีการพัฒนา Java RMI ใหม่ โดยไม่ต้องใช้ Skeleton Layer อีกต่อไป ดังนั้นเราสนใจ Skeleton Layer หรือ Skeleton Class เฉพาะพัฒนา Java RMI กับ JDK 1.0 และ 1.1 เท่านั้น





รูปที่ 3-5 การทำงานของสตับและสเกลเลตัน


3.3 การค้นหา Remote Service


จากกระบวนการต่าง ๆ ที่กล่าวมาในข้างต้น ยังคงมีปัญหาที่ว่า Client นั้น สามารถค้นหา Remote Service ได้อย่างไร รู้ได้อย่างไรว่า Remote Service นั้นอยู่ที่ไหนบนเครือข่าย

            ทางแก้ของปัญหานี้ก็คือ Java RMI ได้มีการใช้ Naming and Directory Service ( เป็น Service ที่ทำการเก็บรักษาออบเจ็กต์ หรือ อ้างอิงออบเจ็กต์ไว้ โดยการอ้างอิงด้วยชื่อ ) ในการเก็บตัวอ้างอิงออบเจ็กต์ของ Remote Service ซึ่ง Client นั้น จะต้องทำการเรียกใช้งาน Naming and Directory Service นี้ ซึ่งก็ทำให้เกิดปัญหาตามมาอีกว่า Client จะรู้ได้อย่างไรว่า Naming and Directory Service นี้อยู่ที่ใด คำตอบก็คือ Naming ane Directory Service นี้ จะทำงานอยู่บน Host และ Port ที่เป็นที่รู้จัก หมายความว่า Client จะต้องรู้ว่ามี Naming and Directory Service นั้นทำงานอยู่ที่ไหน และสามารถเรียกใช้บริการของ Naming and Directory Service นั้นได้โดยตรง

            การทำงานของ Server ผู้ให้บริการ Remote Service นั้น Server จะต้องทำการสร้าง Local Object จาก Class ซึ่งสร้างจาก Remote Service Interface จากนั้นจึงทำการ Export Object นั้นออกไปยัง Java RMI ( การเอ็กซ์พอร์ตทำได้โดย extends UnicastRemoteObject หรือ เรียกใช้ Method ชื่อ exportObject() ) แล้วจึงทำการลงทะเบียนตัวเองเข้ากับ Naming Service ด้วย Public Name ( ชื่อที่ Client รู้จัก ) เพื่อให้ Client สามารถค้นหา Server หรือ Service นั้นจาก Naming Service เจอได้ หลังจากนั้น Client จึงร้องขอใช้บริการ Remote Server

            Client นั้น สามารถเรียกใช้บริการของ Naming Service ได้ผ่านทาง Method ชื่อ lookup() ซึ่งเป็นสแตติก Method ของคลาส Naming ซึ่ง Client จะใช้ Method นี้ ในการค้นหาไปยัง Naming Service ว่ามี Remote Service ที่ต้องการอยู่หรือไม่ โดย Method นี้จะอ้างไปยัง Naming Service โดยผ่านทาง ชื่อโฮสต์, พอร์ต และชื่อของ Remote Service ที่ต้องการค้นหา ถ้าหากพบ Method นี้ จะคืนค่า Remote Reference ไปยัง Remote Service ซึ่ง Client สามารถ เรียก Method ผ่านไปทาง Reference นั้น URL ที่ Client ใช้ในการติดต่อไปยัง Java RMI รีจีสทรี จะอยู่ในรูปแบบดังนั้น

rmi://<host_name>[:<name_service_port>]/<service_name>


โดย host_name คือ Computer Name หรือชื่อที่ DNS ( Domain Name Service ) ในระบบอินเตอร์เน็ตรู้จัก ส่วน name_service_port จำเป็นต้องระบุในกรณีที่ Naming Service นั้นทำงานอยู่บน Port อื่น ๆ นอกจาก Port 1099 ซึ่งเป็นค่า Default


3.4 การสร้างระบบของ Java RMI


            ในหัวข้อนี้จะแสดงตัวอย่างการสร้างระบบออบเจ็กต์แบบกระจายด้วย Java RMI ที่ชื่อว่า Converter Service เป็น Service จะทำการแปลง Integer ที่ Client ส่งมาให้ ให้กลายเป็น String แล้วส่งคืนกลับไปยัง Client และสร้างตัวอย่างของ Client ในการเรียกใช้ Service ดังกล่าว



การสร้างระบบ ออบเจ็กต์แบบกระจายด้วย Java RMI ตามระบบตัวอย่างที่กล่าวมานั้น มีขั้นตอนค่างๆที่ต้องทำดังต่อไปนี้ คือ
  1. สร้าง Interface สำหรับ Service
  2. สร้าง Remote Service จาก Interface ที่สร้างมา
  3. สร้าง Stub & Skeleton Class
  4. สร้าง Service Object ฝัง Server
  5. สร้างโปรแกรมสำหรับเป็น Client
  6. ติดตั้ง Service ไปยัง Java RMI และรันโปรแกรมเพื่อทดสอบ

            การเตรียมการสำหรับตัวอย่างนี้คือสร้าง Folder ไว้สอง Folder สำหรับ Source Code สองส่วน ส่วนแรกสำหรับ Server และส่วนที่สองสำหรับ Client โดยจะมี ไฟล์หนึ่งเป็น Interface ที่จำเป็นต้องใช้สำหรับทั้ง Client และ Server โดยที่เพื่อให้ง่าย ในขั้นตอนนี้เราจะใช้การ ก๊อบปี้ไฟล์ นั้นไปทั้งสอง Folder


3.5 ตัวอย่าง : การสร้างแอพพลิเคชั่น Java RMI เบื้องต้น



คลาสที่ใช้สำหรับตัวอย่างนี้
    Common Classes     ConvertService
    Server Classes     ConvertServer
    ConvertServiceImpl
    Client Classes     ConvertClient


ตารางที่ 3-1 แสดงคลาสที่ใช้สร้างแอพพลิเคชั่น Java RMI เบื้องต้น


3.5.1 Remote Interface


            Interface นี้เป็นคอมมอน Interface ซึ่งทั้ง Client และ Server จะต้องเรียกใช้ได้ จึงต้องมี คลาสนี้สำหรับ ทั้ง Client และ Server โดยที่ Server ที่ทำการแปลงอินทีเจอร์ เป็น สตริงก์ควรจะมี Interface ดังนี้

import java.rmi.*;

public interface ConvertService extends Remote   {

    public String convert( int i ) throws RemoteException
}


แล้วทำการ คอมไพล์ Interface นี้ให้เป็น คลาสไฟล์ด้วยคำสั่ง


> javac ConvertService.java

ใน Interface นี้มีสิ่งที่น่าสนใจคือ
  • จะต้อง extends java.rmi.Remote เพื่อบอกถึงการเป็น Remote Object สำหรับ Java RMI
  • ในทุก ๆ Method ใน Interface จะต้อง throws จาก java.rmi.RemoteException


3.5.2 การสร้าง Remote Service


            Remote Service ก็คือออบเจ็กต์ ซึ่ง สร้างจาก Remote Interface ที่สร้างไว้นั่นเอง ซึ่งการแยกส่วนระหว่าง Interface และส่วนอิมพลีเมนเทชันนั้น สำคัญมากสำหรับทั้ง Java RMI และ Jini

            มีหลายวิธีที่จะสร้าง Remote Service แต่วิธีที่ง่ายที่สุดน่าจะเป็นการ extends คลาสนั้นด้วยคลาส java.rmi.server.UnicastRemoteObject ซึ่ง คลาสนี้นั้นจะดูแลเรื่องการส่ง รีเฟอร์เรนซ์ของรีโมตออบเจ็กต์ไปยัง Server และ Client และการเรียกใช้ Method ระหว่างสองส่วนนั้น หรืออีกวิธีหนึ่งที่สามารถใช้ได้ก็คือการเรียกใช้ สแตติก Method ที่ชื่อ exportObject() ของคลาส UnicastRemoteObject ตัวอย่าง การสร้าง Remote Service คือ

import java.rmi.*;
import java.rmi.server.*;

public class ConvertServiceImpl extends UnicastRemoteObject implements ConvertService   {

    public ConvertServiceImpl()   {

    }

    //Called by the RMI infrastructure when the client
    //invokes the remote method

    public String convert( int i ) throws RemoteException   {

            return new Integer(i).toString();
    }
}


แล้วทำการคอมไพล์คลาสนี้ให้เป็นคลาสไฟล์ด้วยคำสั่ง

> javac ConvertServiceImpl.java

ในคลาสนี้มีสิ่งที่น่าสนใจคือ
  • คอนสตรักเตอร์ Method ของ UnicastRemoteObject มีการ throws RemoteException ด้วยดังนั้นคอนสตรักเตอร์ Method ของ ConvertServiceImpl จึงต้อง throw RemoteException ด้วย
  • ออบเจ็กต์และ Method ของคลาสนี้ทำงานอยู่บน Server เพราะฉะนั้นรีซอร์สต่าง ๆ ที่ Server ต้องการจะต้องมีให้ด้วย (เช่นคลาส Interface )
  • หากมี Client หลายโปรแกรมที่มาเรียกใช้ Method ชื่อ convert()


Client แต่ละตัวนั้นจะเชื่อมต่อเข้ามาในเธรดที่แยกจากกันเพราะฉะนั้น Method นี้ จะถูกเรียกให้ทำงานพร้อมกันจากหลาย Client ถ้าหาก Service ที่ต้องการจะสร้างไม่ต้องการให้มีการทำงานที่ซ้อนกันจะต้องใช้ การทำ ซิงโครไนเซชันเข้ามาช่วย


3.5.3 การสร้างสตับและสเกลเลตัน


            การสร้างสตับและสเกลเลตันสำหรับ Remote Service นี้ทำได้โดยการใช้ Java RMI คอมไพเลอร์ ซึ่งมีมาให้กับชุดของ JDK ที่ชื่อ “rmic” เพื่อใช้ในการสร้างสตับและสเกลเลตันไฟล์ซึ่ง คอมไพเลอร์นี้จะใช้ในการ คอมไพล์คลาสไฟล์ของ Remote Service ด้วยคำสั่ง



> rmic ConvertServiceImpl ( สำหรับ JDK 1.0 ขึ้นไป )

> rmic -v1.2 ConvertServiceImpl ( สำหรับ J2SE 1.2 ขึ้นไป )

ซึ่งคำสั่งนี้จะทำการสร้างไฟล์ที่ชื่อ ConvertServiceImpl_Stub.class ( Stub Class ) และ ConvertServiceImpl_Skel.class ( Skeleton Class แต่ไม่จำเป็นสำหรับ Java RMI ตั้งแต่ J2SE 1.2 ขึ้นไป )


3.5.4 การสร้าง Server สำหรับ Remote Service


            Service ของ Java RMI จะต้องถูกสร้างขึ้นมาในโพรเซสของ Server จากนั้นจึงทำการ ลงทะเบียน Service ไปที่ Naming Service เพื่อให้ Client สามารถเรียกใช้ได้ ด้วยสแตติก Method ชื่อ rebind() ของคลาส Naming ซึ่งพารามิเตอร์เป็น URL สำหรับ Naming Service และออบเจ็กต์ที่จะลงทะเบียน ตัวอย่างของ Server มีดังนี้

import java.rmi.*;

public class ConvertServer   {

    public ConvertServer()   {

        try   {

                ConvertService c = new ConvertServiceImpl();

                Naming.rebind(“rmi://localhost:1099/ConvertService”,c);
        }

        catch( Exception ex )   {

                System.out.println( “Troble:” + ex );
        }
    }

    public static void main( String[] args )   {

            new ConvertServer();
    }
}


แล้วทำการคอมไพล์คลาสนี้ให้อยู่ในรูปของคลาสไฟล์ด้วยคำสั่ง

> javac ConvertService.java

3.5.5 การสร้างโปรแกรมสำหรับ Client


            สิ่งที่ Client โปรแกรมจะต้องทำมีสองอย่างคือ ค้นหาออบเจ็กต์ของ Remote Service ที่ต้องการ แล้วทำการเรียกใช้ Method ของ Remote Service นั้น การค้นหาออบเจ็กต์ของ Remote Service นั้นสามารถทำได้อย่างง่ายๆโดยเรียกใช้ สแตติก Method ที่ชื่อ lookup() ซึ่งเป็นของ คลาส Naming ส่วนการเรียกใช้ Method ของรีโมตออบเจ็กต์นั้นก็สามารถทำได้เหมือนกับการเรียกใช้ Method ของโลคอลออบเจ็กต์ธรรมดา ตัวอย่างของ Client คือ

import java.rmi.*;

public class ConvertClient   {

    public static void main( String[] args ) throws Exception   {

        ConvertService cs = (ConvertService)Naming.lookup(“ConvertService”);

        try   {

                System.out.println(“The result is ”+cs.convert(152));
        }

        catch( RemoteException ex )   {

                System.out.println( “Can’t convert integer ” + ex );
        }
    }
}

ในการที่ Client จะสามารถทำงานกับรีโมตออบเจ็กต์ใด ๆ Client จะเรียกการทำงานผ่านไปทางสตับของ รีโมตออบเจ็กต์นั้น ซึ่งจากตัวอย่าง เราจะต้อง ก๊อบปี้ไฟล์ที่เป็นสตับของ ConvertServiceImpl ที่ชื่อ ConvertServiceImpl_Stub.class มาใส่ไว้ใน classpath ของ Client ด้วย Client จึงจะทำงานได้ แต่ในส่วนของการคอมไพล์นั้น Client ต้องการเพียง Interface คลาสในการคอมไพล์เท่านั้น จึงต้องนำคลาส Interface มาใส่ไว้ที่ Directory ของ Client ด้วยจากนั้นจึง คอมไพล์ Client ด้วยคำสั่ง

> javac ConvertClient.java



3.5.6 การเริ่มการทำงานของระบบ Java RMI


            จากการที่ได้เตรียมการไว้ในตอนแรกว่าให้แยก ไดเรกทอรี่ระหว่างซอร์สโค้ดของ Client กับซอร์สโค้ดของ Server ก็เพื่อจำลองสภาวะแวดล้อมให้เหมือนกับการอยู่ต่างที่กันใน ระบบเครือข่ายโดยที่

ในส่วนของ Server จะต้องมีคลาสดังต่อไปนี้
  • Conass เป็น Remote Service
  • ConvertServiceImpl.class เป็นตัว Remote Service
  • ConvertServiceImpl_Stub.class เป็นสตับของ Remote Service
  • ConvertServiceImpl_Skel.class เป็นสเกลเลตันของ Remote Service
  • ConvertServer.class เป็น Server ของ Remote Service

ส่วนในฝั่งของ Client จะต้องมีคลาสดังต่อไปนี้
  • ConvertService.class เป็น Remote Service
  • ConvertServiceImpl_stub.class เป็นสตับของ Remote Service ใช้ในการคุยกับ Service
  • ConvertClient.class
  • vertService.class ทำหน้าที่เป็น Client ที่เรียกใช้ Remote Service

วิธีการในการ เริ่มการทำงานของ Remote Service คือ
  1. เริ่มการทำงานของ Naming Service ที่ชื่อ rmiregistry ที่ฝั่ง Server ที่ดีฟอลต์พอร์ต 1099 ด้วยคำสั่ง

        server > rmiregistry

  2. เริ่มการทำงานของ Server ด้วยคำสั่ง

        server > java ConvertService

  3. เริ่มการทำงานของ Client ด้วยคำสั่ง

        client > java ConvertClient

    ถ้าหากการทำงานไม่มีปัญหาอะไรก็จะได้ Output ดังนี้

        client > The result is 152


3.6 การกระจายคลาสไฟล์โดยอัตโนมัติ


            จากตัวอย่างที่ได้แสดงไว้ข้างต้นจะเห็นได้ว่า จะต้องมีคลาสที่ใช้สำหรับทั้ง Client และ Server และ Client ก็ยังต้องการ คลาสบาง คลาสที่สร้างโดย Server อีกด้วย ซึ่งวิธีการที่ใช้ในตัวอย่างนี้เราใช้การก๊อบปี้คลาสไปยังไดเรกทอรี่ที่ต้องการซึ่งวิธีนี้ก็สามารถทำได้ แต่ว่าในการนำไปใช้จริง คงจะเป็นเรื่องยากที่จะต้องคอย ก๊อบปี้ไฟล์ของ Server ส่งไปยัง Client ถ้าหาก Client กับ Server อยู่ห่างไกลกัน ทาง ผู้ออกแบบ Java RMI จึงได้ออกแบบส่วนขยายของ การทำ คลาสโหลดดิ้ง โดยเพิ่มส่วนที่ทำให้สามารถ ดาวน์โหลดคลาสผ่านทาง FTP Server หรือ HTTP Server ได้

            RMI สามารถรองรับการทำ การโหลดคลาสระยะไกลโดยผ่านทาง RMIClassLoader ถ้าหาก Client ทำงานอยู่บนระบบของ Java RMI แล้วระบบพบว่าจำเป็นต้องมีการ โหลดคลาสผ่านทาง รีโมตโลเคชัน ระบบก็จะทำการเรียกไปยัง RMIClassLoader เพื่อทำการ โหลดคลาส

            การโหลดคลาสของ Java RMI จะถูกควบคุมด้วย ค่าพารามิเตอร์จำนวนหนึ่งซึ่ง พารามิเตอร์ต่าง ๆ เหล่านี้สามารถถูกตั้งค่าได้เมื่อ JVM แต่ละตัวเริ่มทำงานด้วยคำสั่ง


> java [ -D<PropertyName>=<PropertyValue> ] + <ClassFile>

โดยที่ พารามิเตอร์ java.rmi.server.codebase นั้นถูกใช้สำหรับบอก URL ที่ RMIClassLoader ใช้ในการโหลดคลาสซึ่ง URL นี้จะชี้ไปยัง file:, ftp:, http: ที่มีคลาสนั้นให้บริการอยู่ซึ่งออบเจ็กต์ อื่น ๆ ใช้ในการโหลดคลาสสำหรับออบเจ็กต์ที่ได้รับมาจาก JVM นั้น (ใช้กับการทำ คลาสแคสท์ (Class Cast) สำหรับกระบวนการดีซีเรียลไลเซชัน) หรือใช้สำหรับเรียกคลาสที่ต้องการมาใช้ เช่น Client จะเรียกใช้สตับคลาสของ Server ก็สามารถทำโดยผ่าน RMIClassLoader ได้เช่นเดียวกัน

ตัวอย่างวิธีการใช้งาน RMIClassLoader เราสามารถทำได้โดยการ
  1. เริ่มการทำงานของ Web Server (http server) ที่พอร์ตที่ต้องการ เช่น 8080
  2. นำ คลาสที่ต้องการจะทำการ โหลดผ่าน RMIClassLoader ไปใส่ไว้ที่ Web Server
  3. การเริ่มการทำงานของ JVM ที่จะต้องการให้ใช้ RMIClassLoader โดยกำหนดพารามิเตอร์ให้กับ JVM ดังนี้

        server > java –Djava.rmi.server.codebase=http://your_host:8080 ConvertService


หากเรานำ คลาส ConvertServiceImpl_Stub.class ไปใส่ไว้ที่ http://your_host/ เราก็ไม่จำเป็นจะต้องก๊อบปี้คลาสนั้นไปใส่ไว้ในไดเรกทอรี่เดียวกับ ConvertService โดยที่ RMIClassLoader จะทำการโหลดคลาส ConvertServiceImpl_Stub.class มาให้เองโดยอัตโนมัติ





Last update : June 17, 2009 17:00 ( Thailand )

Apple, Mac, iMac, iPhone and iPod are trademarks of Apple, Inc.

Jini, Java and all Java-based are trademarks of Sun Microsystems, Inc.



JiniSoft Corporation

Copyright @ 1990 - 2009   Mr. Roongroj Rojanapo ( )

99/2 Soi Ramindra 14, Ramindra Road, Bangkane, Bangkok 10230, Thailand


E-mail : roongroj @ mac.com
SMS : 081 615-5135  ( iPhone )
FAX : 02   943-6433