• stub 和 skeleton 的讲解,自己实现一个stub和skeleton程序


    转:

    RMI的本质就是实现在不同JVM之间的调用,它的实现方法就是在两个JVM中各开一个Stub和Skeleton,二者通过socket通信来实现参数和返回值的传递。

         有关RMI的例子代码网上可以找到不少,但绝大部分都是通过extend the interface java.rmi.Remote实现,已经封装的很完善了,不免使人有雾里看花的感觉。下面的例子是我在《Enterprise JavaBeans》里看到的,虽然很粗糙,但很直观,利于很快了解它的工作原理。

    Ⅰ:RMI工作原理(自定义实现一个Stub 和 Skeleton)

    1. 定义一个Person的接口,其中有两个business method, getAge() 和getName()

    Person代码:

    1. public interface Person {      
    2.     public int getAge() throws Throwable;      
    3.     public String getName() throws Throwable;      
    4. }

    2. Person的实现PersonServer类

    PersonServer代码:

    1. public class PersonServer implements Person {      
    2.     private int age;      
    3.     private String name;      
    4.     public PersonServer(String name, int age) {      
    5.         this.age = age;      
    6.         this.name = name;      
    7.     }      
    8.     public int getAge() {      
    9.         return age;      
    10.     }      
    11.     public String getName() {      
    12.         return name;      
    13.     }      
    14. }     

    3. 好,我们现在要在Client机器上调用getAge()和getName()这两个business method,那么就得编写相应的Stub(Client端)和Skeleton(Server端)程序。这是Stub的实现:

    Person_Stub代码:

    //存根(stub)Person_Stub的实现:

    1. import java.io.ObjectOutputStream;      
    2. import java.io.ObjectInputStream;      
    3. import java.net.Socket;      
    4. public class Person_Stub implements Person {      
    5.     private Socket socket;      
    6.     public Person_Stub() throws Throwable {      
    7.         // connect to skeleton      
    8.         socket = new Socket("computer_name", 9000);      
    9.     }      
    10.     public int getAge() throws Throwable {      
    11.         // pass method name to skeleton      
    12.         ObjectOutputStream outStream =      
    13.             new ObjectOutputStream(socket.getOutputStream());      
    14.         outStream.writeObject("age");      
    15.         outStream.flush();      
    16.         ObjectInputStream inStream =      
    17.             new ObjectInputStream(socket.getInputStream());      
    18.         return inStream.readInt();      
    19.     }      
    20.     public String getName() throws Throwable {      
    21.         // pass method name to skeleton      
    22.         ObjectOutputStream outStream =      
    23.             new ObjectOutputStream(socket.getOutputStream());      
    24.         outStream.writeObject("name");      
    25.         outStream.flush();      
    26.         ObjectInputStream inStream =      
    27.             new ObjectInputStream(socket.getInputStream());      
    28.         return (String)inStream.readObject();      
    29.     }      
    30. }     

    注意,Person_Stub和PersonServer一样,都implements Person。它们都实现了getAge()和getName()两个business method,不同的是PersonServer是真的实现,Person_Stub是建立socket连接,并向Skeleton发请求,然后通过Skeleton调用PersonServer的方法,最后接收返回的结果。

    4. 骨架(Skeleton)的实现

    Person_Skeleton代码:

    1. import java.io.ObjectOutputStream;      
    2. import java.io.ObjectInputStream;      
    3. import java.net.Socket;      
    4. import java.net.ServerSocket;      
    5. public class Person_Skeleton extends Thread {      
    6.     private PersonServer myServer;      
    7.     public Person_Skeleton(PersonServer server) {      
    8.         // get reference of object server      
    9.         this.myServer = server;      
    10.     }      
    11.     public void run() {      
    12.         try {      
    13.             // new socket at port 9000      
    14.             ServerSocket serverSocket = new ServerSocket(9000);      
    15.             // accept stub's request      
    16.             Socket socket = serverSocket.accept();      
    17.             while (socket != null) {      
    18.                 // get stub's request      
    19.                 ObjectInputStream inStream =      
    20.                     new ObjectInputStream(socket.getInputStream());      
    21.                 String method = (String)inStream.readObject();      
    22.                 // check method name      
    23.                 if (method.equals("age")) {      
    24.                     // execute object server's business method      
    25.                     int age = myServer.getAge();      
    26.                     ObjectOutputStream outStream =      
    27.                         new ObjectOutputStream(socket.getOutputStream());      
    28.                     // return result to stub      
    29.                     outStream.writeInt(age);      
    30.                     outStream.flush();      
    31.                 }      
    32.                 if(method.equals("name")) {      
    33.                     // execute object server's business method      
    34.                     String name = myServer.getName();      
    35.                     ObjectOutputStream outStream =      
    36.                         new ObjectOutputStream(socket.getOutputStream());      
    37.                     // return result to stub      
    38.                     outStream.writeObject(name);      
    39.                     outStream.flush();      
    40.                 }      
    41.             }      
    42.         } catch(Throwable t) {      
    43.             t.printStackTrace();      
    44.             System.exit(0);      
    45.         }      
    46.     }      
    47.     public static void main(String args []) {      
    48.         // new object server      
    49.         PersonServer person = new PersonServer("Richard", 34);      
    50.         Person_Skeleton skel = new Person_Skeleton(person);      
    51.         skel.start();      
    52.     }      
    53. }     

      

    Skeleton类 extends from Thread,它长驻在后台运行,随时接收client发过来的request。并根据发送过来的key去调用相应的business method。

    5. 最后一个,Client的实现

    PersonClient 代码:

    1. public class PersonClient {      
    2.     public static void main(String [] args) {      
    3.         try {      
    4.             Person person = new Person_Stub();      
    5.             int age = person.getAge();      
    6.             String name = person.getName();      
    7.             System.out.println(name + " is " + age + " years old");      
    8.         } catch(Throwable t) {      
    9.             t.printStackTrace();      
    10.         }      
    11.     }      
    12. }      

    Client(PersonClient)的本质是,它要知道Person接口的定义,并实例一个Person_Stub,通过Stub来调用business method,至于Stub怎么去和Server沟通,Client就不用管了。

    注意它的写法:

    Person person = new Person_Stub();而不是Person_Stub person = new Person_Stub();为什么?因为要面向接口编程嘛,呵呵。

    //RMI实质上就是生成2个类stub,skeleton来进行参数和返回值的传递,采用值传递方式

    //类似于以前写的聊天室程序,被传递的对象应实现java.io.Serializable接口

  • 相关阅读:
    制作一个简单的轮播图
    JS 与 jQery 的区别主要在于 DOM
    JS学习第九天
    JS学习第八天
    JS学习第七天
    JS学习第六天
    Luogu1175 | 表达式的转换 (表达式树)
    adworld int_overflow | 整形溢出
    蓝桥杯第十一届软件类校内模拟赛题解(下)
    蓝桥杯第十一届软件类校内模拟赛题解(上)
  • 原文地址:https://www.cnblogs.com/libin6505/p/11429578.html
Copyright © 2020-2023  润新知