How to using RMI(转)
May 7, 2007步驟:
1. 定義一個遠端物件,可供主從雙方相互導循
2. 為遠端類別建立和編譯實作的類別
3. 使用rmic的命令建立類別stub和skeleton
C:\rmic MyBBSImpl
4. 建立和編譯一個伺服器的應用程式
5. 建立和編譯一個存取遠端物件的客戶端程式
6. 啟動RMI Registry和伺服器應用程式
C:\Start rmiregistry
——————————————————————————–
一、定義遠端物件
- 描述客戶端要如何呼叫遠端的方法
public interface MyBBS extends java.rmi.Remote {
public void MyBBSClientInit() throws java.rmi.RemoteException; //系統初始化
public String post(String NewMessage)throws java.rmi.RemoteException;//張貼一個新的訊息
public String getExistMessage() throws java.rmi.RemoteException;//回傳所有在BBS上所存在的訊息
public String getUserName() throws java.rmi.RemoteException; //回傳目前的使用者名稱
public String getUserList() throws java.rmi.RemoteException;//回傳系統上所有在線上的使用使
public void onClose(String currentUser) throws java.rmi.RemoteException;//關閉一個用戶端程式
}
二 、實作遠端物件類別
UnicastRemoteObject
– 要製作遠端物件,其子類別需繼承UnicastRemoteObject並宣告它實作的MyBBS的遠端介面
– 其作用是將物件的引數與傳回值轉換成可通過網路的位元組串流
import java.util.*;
public class MyBBSImpl extends java.rmi.server.UnicastRemoteObject implements MyBBS {
static String message=”Welcome to my BBS, you are the first user!\n”;
static Vector userList=new Vector();
static Vector clientList=new Vector();
static int userNum=0;
public MyBBSImpl(String message) throws java.rmi.RemoteException {
super();
this.message=message;
}
public void MyBBSClientInit() throws java.rmi.RemoteException {
userNum++;
Integer N=new Integer(userNum);
userList.addElement(”User”+N.toString());
}
public String post(String NewMessage)throws java.rmi.RemoteException {
message=message+”\n”+NewMessage;
return message;
}
public String getExistMessage() throws java.rmi.RemoteException {
return message;
}
public String getUserName() throws java.rmi.RemoteException {
return userList.lastElement().toString() ;
}
public String getUserList() throws java.rmi.RemoteException {
String list=”";
for (int i=0; i
}
return list;
}
public void onClose(String currentUser) throws java.rmi.RemoteException {
userNum–;
userList.removeElement(currentUser);
}
}
三、Stub的編譯
c:\rmic MyBBSImpl
即會產生MyBBSImpl_Stub.class和MyBBSImpl_Skel.class
- MyBBSImpl.class、MyBBSServer.class、MyBBSImpl_Skel.class是放於Server端
- 而MyBBSImpl_Stub.class則放於Client端
四、伺服器
‧ 寫一個將遠端物件(MyBBSImpl)供給外界的伺服器
- 建立遠端物件
- 將遠端物件註冊到Registry
‧ Naming / Registry service
– 所謂的Naimg就是向當地遠端物件註冊到registry
– registry是登記每一個遠端物件的註冊名稱,以好讓客戶端可以索取遠端物件的名單。
URL: rmi://hostname:port/servicename
‧ default port: 1099 rmi://localhost/Bank
‧ default host: localhost rmi://:1099/MyBBSService rmi:///MyBBSService
import java.rmi.Naming;
public class MyBBSServer {
public MyBBSServer() {
try {
MyBBS bbs=new MyBBSImpl(”");
Naming.rebind(”rmi://localhost:1099/MyBBSService”,bbs);//使用rebind的方法向Registry註冊Service
} catch (Exception e) {
System.out.println(”MyBBS Trouble:”+e);
}
}
public static void main(String args[]) {
new MyBBSServer();
}
}
四、客戶端:
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.net.MalformedURLException;
import java.rmi.NotBoundException;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MyBBSClient extends JFrame implements Runnable {
private JLabel welcomeLabel;
private JTextField myMessage;
private JTextArea messageBoard, userListArea;
public MyBBS bbs;
private String existMessage=”";
private String userName=”";
private String userList=”";
public MyBBSClient(String host) {
super(”Welcome to my BBS”);
try {
bbs=(MyBBS) Naming.lookup(”rmi://”+host+”/MyBBSService”);// 使用lookup至遠端搜尋所提供的service
}
catch (MalformedURLException murle) {
System.out.println();
System.out.println(”MalformedURLException”);
System.out.println(murle);
}
catch (RemoteException re) {
System.out.println();
System.out.println(”RemoteException”);
System.out.println(re);
}
catch (NotBoundException nbe) {
System.out.println();
System.out.println(
“NotBoundException”);
System.out.println(nbe);
}
catch (java.lang.ArithmeticException ae) {
System.out.println();
System.out.println(”java.lang.ArithmeticException”);
System.out.println(ae);
}
try {
bbs.MyBBSClientInit();
existMessage=bbs.getExistMessage();
userName=bbs.getUserName();
userList=bbs.getUserList();
}
catch (RemoteException re) {
System.out.println();
System.out.println(”RemoteException”);
System.out.println(re);
}
catch (java.lang.ArithmeticException ae) {
System.out.println();
System.out.println(”java.lang.ArithmeticException”);
System.out.println(ae);
}
Container c=getContentPane();
c.setLayout(new BorderLayout(5,5));
welcomeLabel=new JLabel();
welcomeLabel.setText(”Welcome “+userName+” !”);
c.add(welcomeLabel,BorderLayout.NORTH);
messageBoard=new JTextArea(10,30);
messageBoard.setEditable(false);
messageBoard.setText(existMessage);
c.add(messageBoard,BorderLayout.WEST);
c.add(new JScrollPane(messageBoard));
userListArea=new JTextArea(10,20);
userListArea.setEditable(false);
userListArea.setText(”Current Online Users:”+userList);
c.add(userListArea,BorderLayout.EAST);
myMessage=new JTextField(”Input your message here”,20);
c.add(myMessage,BorderLayout.SOUTH);
MyBBSHandler handler=new MyBBSHandler();
myMessage.addActionListener(handler);
setSize(500,500);
setResizable(false);
show();
}
public void run() { //一個客戶端程式起動一個thread去update BBS上的訊息
while (true) {
try {
Thread.sleep(1000);
try {
existMessage=bbs.getExistMessage();
userList=bbs.getUserList();
welcomeLabel.setText(”Welcome “+userName+” !”);
messageBoard.setText(existMessage);
userListArea.setText(”Current Online Users:”+userList);
show();
}
catch (RemoteException re) {
System.out.println();
System.out.println(”RemoteException”);
System.out.println(re);
}
catch (java.lang.ArithmeticException ae) {
System.out.println(”java.lang.ArithmeticException”);
System.out.println(ae);
}
Thread.yield();
}
catch (Exception e) {
return;
}
}
}
public void CloseClient(){ //關閉客戶端的程式
try {
bbs.onClose(userName);
show();
}
catch (RemoteException re) {
System.out.println();
System.out.println(”RemoteException”);
System.out.println(re);
}
catch (java.lang.ArithmeticException ae) {
System.out.println();
System.out.println(”java.lang.ArithmeticException”);
System.out.println(ae);
}
}
public void show() { //顯示和更新客戶端的介面
try {
existMessage=bbs.getExistMessage();
userList=bbs.getUserList();
welcomeLabel.setText(”Welcome “+userName+” !”);
messageBoard.setText(existMessage);
userListArea.setText(”Current Online Users:”+userList);
super.show();
}
catch (RemoteException re) {
System.out.println();
System.out.println(”RemoteException”);
System.out.println(re);
}
catch (java.lang.ArithmeticException ae) {
System.out.println();
System.out.println(”java.lang.ArithmeticException”);
System.out.println(ae);
}
}
public static void main (String args[]) {
String host=”localhost”;
if (args.length!=0)
host=args[0];
final MyBBSClient bbsClient=new MyBBSClient(host);
Thread BBSThread=new Thread (bbsClient);
BBSThread.start();
bbsClient.addWindowListener (
new WindowAdapter() {
public void windowClosing(WindowEvent e) {
bbsClient.CloseClient();
System.exit(0);
}
}
);
}
private class MyBBSHandler implements ActionListener {
public void actionPerformed (ActionEvent e)
{
String s=”";
if (e.getSource()==myMessage){
try {
s=bbs.post(userName+”: “+e.getActionCommand());
}
catch (RemoteException re) {
System.out.println();
System.out.println(”RemoteException”);
System.out.println(re);
}
catch (java.lang.ArithmeticException ae) {
System.out.println();
System.out.println(”java.lang.ArithmeticException”);
System.out.println(ae);
}
myMessage.setText(”");
messageBoard.setText(s);
show();
}
}
}
}

