▣ RMI(Remote Method Invocation)
   - 분산 시스템 구축시 Socket 방식을 이용하는 것보다 간결하고 신속함
   - RPC(Remote Procedure Call) : 원격지의 함수 호출, C 언어에서 사용
   - CORBA의 분산 객체 시스템과 비슷(이기종 간의 분산 처리 구축, 코바서버를 2중으로 구축시 모든 서버에서 트랜잭션이 안정적으로 진행이 안됨)
   - 원리
                       Client Area ↓                ↓Server Area 
     -----------------------------------------------------------------------------------------
     Local System --> Class --> Stub --> NETWORK --> Stub --> Skeleton --> Class Remote System
                   결과전송 <-- Stub <-- NETWORK <----------- Skeleton <-- 비지니스 로직 처리                

 


1. RMI 프로그래밍 순서도
   ① 원격 인터페이스 정의
   ② 원격 객체 구현
   ③ javac 컴파일 - 원격 객체 클래스
   ④ rmic - Stub, Skeleton class 생성
   ⑤ 로컬 객체 클래스 제작  
   ⑤ RMI 등록 서버 실행
   ⑥ 클라이언트 접속

 


2. UnicastRemoteObject 의 상속 구조

     public abstract class RemoteObject extends Object implements Remote, Serializable
     --> java.lang.Object 클래스의 hashCode(), equals(), toString() 메소드를 구현해서 갖고 있는 클래스
     ↑
     public abstract class RemoteServer extends RemoteObject
     --> 원격지 메소드 참조에 대한 구현에 대한 FrameWork을 갖고 있는 최상위 클래스
     ↑
     public class UnicastRemoteObject extends RemoteServer
     -->  tcp 상에서 object reference를 참조할 수 있도록 지원해 주는 클래스

 


3. Echo 예제 실습
--------------------------------------------------------------------------
구분  CLIENT SIDE SERVER SIDE
--------------------------------------------------------------------------
Interface            Echo.class  Echo.class

Remote Object   EchoImpl.class

Proxy  EchoImpl_Stub.class EchoImpl_Stub/Skel.class

Run Class            EchoClient.class EchoServer.class
--------------------------------------------------------------------------
실행 순서
1. rmic EchoImp
2. start rmiregistry   <-- C:\Program Files\Oracle\jre\1.1.7\bin; 경로가 PATH에 있으면 제거하고 시스템 재 시작합니다.
3. java EchoServer
4. java EchoClient nulunggi


------------------------ e.bat ------------------------
rmic EchoImpl
start rmiregistry
rem ---------
rem 서버 작동
rem ---------
java EchoServer

 

1/4-------------------------- Echo.java --------------------------
import java.rmi.RemoteException;

import java.rmi.Remote;

public interface Echo extends Remote{
  public String sayEcho(String name) throws RemoteException;
}


2/4-------------------------- EchoImpl.java --------------------------
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class EchoImpl extends UnicastRemoteObject implements Echo{
 String message;

 public EchoImpl() throws RemoteException{}

 public EchoImpl(String message) throws RemoteException{
  this.message = message;
 }

 public String sayEcho(String name){
  return "\n 엄기흥 강사 PC 로 부터 전송된 문자열 : " + message + " " + name + "님 \n";
 }
}
 

3/4-------------------------- EchoServer.java --------------------------
import java.rmi.Naming;

public class EchoServer{
  public static void main(String args[]){
    try{
      EchoImpl echoRef = new EchoImpl();
      Naming.bind("Echo",echoRef);
    }catch( java.rmi.AlreadyBoundException e){
      e.printStackTrace();  
    }catch(java.net.MalformedURLException e ){
      e.printStackTrace();
    }catch( java.rmi.RemoteException e){
      e.printStackTrace();   
    }
    System.out.println("--------------------------------");
    System.out.println("Echo RMI 서버가 작동 되었습니다.");
    System.out.println("--------------------------------");
  }
}


4/4-------------------------- EchoClient.java --------------------------
import java.rmi.Naming;
import java.rmi.*;
import java.net.*;

public class EchoClient{
 public static void main(String args[]){
  String url = "rmi://127.0.0.1/Echo";
                     //String url = "rmi://" + args[0] + "/Echo";

  Echo echoRef = null;
  try{
   echoRef = (Echo)Naming.lookup(url);

   System.out.println(echoRef.sayEcho(args[0]));
  }catch(RemoteException e){
   e.printStackTrace();
  }catch(MalformedURLException e){
   e.printStackTrace();
  }catch(NotBoundException e){
   e.printStackTrace();
  }
  
 }
}

 


4. RMI 서버 모듈의 분리 예제
--------------------------------------------------------------------------
구분  CLIENT SIDE        SERVER SIDE
--------------------------------------------------------------------------
Interface            Echo.class         Echo.class
                      EchoFactory.class           EchoFactory.class

Remote Object          EchoImpl.class
                                                  EchoFactoryImpl.class 

Proxy  EchoImpl_Stub.class        EchoImpl_Stub/Skel.class
                     EchoFactoryImpl_Stub.class   EchoFactoryImpl_Stub/Skel.class

Run Class            EchoFactoryClient.class      EchoFactoryServer.class
Start File           s.bat                        r.bat
--------------------------------------------------------------------------


실행 방법 : r.bat
rem ---------------------------------------
rem 파일 내용 : Echo 예제 배치파일 입니다.
rem 작성일 : 2002-01-01
rem 작성자 : 엄기흥
rem ---------------------------------------
rmic EchoImpl
rmic EchoFactoryImpl
start rmiregistry.exe
java EchoFactoryServer

 


1/6------------------------ Echo.java ------------------------
import java.rmi.RemoteException;

import java.rmi.Remote;

public interface Echo extends Remote{
  public String sayEcho(String name) throws RemoteException;
}


2/6------------------------ EchoImpl.java ------------------------
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class EchoImpl extends UnicastRemoteObject implements Echo{
 String message;

 public EchoImpl() throws RemoteException{}

 public EchoImpl(String message) throws RemoteException{
  this.message = message;
 }

 public String sayEcho(String name){
  return "\n " + message + " " + name + "님 \n";
 }
}


3/6------------------------ EchoFactory.java ------------------------
import java.rmi.RemoteException;
import java.rmi.Remote;

public interface EchoFactory extends Remote{
  public Echo getEcho(String greeting) throws RemoteException;
}


4/6------------------------ EchoFactoryImpl.java ------------------------
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class EchoFactoryImpl extends UnicastRemoteObject implements EchoFactory{
 
  public EchoFactoryImpl() throws RemoteException{}

  public Echo getEcho(String message) throws RemoteException{
    EchoImpl echoRef = new EchoImpl(message);
    return (Echo)echoRef;
  }

}


5/6------------------------ EchoFactoryServer.java ------------------------
import java.rmi.Naming;

public class EchoFactoryServer {
 public static void main(String args[]) throws Exception{
  EchoFactoryImpl factoryRef = new EchoFactoryImpl();

  Naming.rebind("EchoFactory",factoryRef);
  
  System.out.println("서버가 시작되었습니다.");
 }
}


6/6------------------------ EchoFactoryClient.java ------------------------
import java.rmi.Naming;
import java.rmi.*;
import java.net.*;

public class EchoFactoryClient{
  public static void main(String args[]){
   
 //String url = "rmi://127.0.0.1/EchoFactory";

 EchoFactory ref = null;

 try{
  if (args.length != 2){
                        System.out.println("파라미터가 잘못되었습니다.");
   System.out.println("사용법 : java EchoFactoryClient nulunggi 211.108.242.114");
   System.exit(1);
  }

  ref = (EchoFactory)Naming.lookup("rmi://" + args[1] + "/EchoFactory");

  Echo echoHello = ref.getEcho("수고하셨습니다.");
  Echo echoGood = ref.getEcho("2개월간 고생하셨습니다.");

  System.out.println(echoHello.sayEcho(args[0])); 
  System.out.println(echoGood.sayEcho(args[0])); 

 }catch(RemoteException e){
  e.printStackTrace();  
 }catch(MalformedURLException e){
  e.printStackTrace(); 
 }catch(NotBoundException e){
  e.printStackTrace(); 
 }

  }
}

 


▣ RMI + Thread를 이용하여 여러 컴퓨터에서 계산하기

------------------------ e.bat ------------------------
rmic EchoImpl
start rmiregistry
rem ---------
rem 서버 작동
rem ---------
java EchoServer

 


1. 서버쪽 수정 EchoImpl.java

1/4-------------------------- Echo.java --------------------------
import java.rmi.RemoteException;

import java.rmi.Remote;

public interface Echo extends Remote{
  public String sayEcho(String name) throws RemoteException;
}


2/4-------------------------- EchoImpl.java --------------------------
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class EchoImpl extends UnicastRemoteObject implements Echo{
 String message;

 public EchoImpl() throws RemoteException{}

 public EchoImpl(String message) throws RemoteException{
  this.message = message;
 }

 public String sayEcho(String name){

             int i=1;
             long hap=0;

             for(long q=1; q<=500000000; q++){
                       hap = hap + q;
             }
    return i + "번째 1부터 500,000,000까지의 합 : " + hap + "\n";

 }
}
 

3/4-------------------------- EchoServer.java --------------------------
import java.rmi.Naming;

public class EchoServer{
  public static void main(String args[]){
    try{
      EchoImpl echoRef = new EchoImpl();
      Naming.bind("Echo",echoRef);
    }catch( java.rmi.AlreadyBoundException e){
      e.printStackTrace();  
    }catch(java.net.MalformedURLException e ){
      e.printStackTrace();
    }catch( java.rmi.RemoteException e){
      e.printStackTrace();   
    }
    System.out.println("--------------------------------");
    System.out.println("Thread용 Echo RMI 서버가 작동 되었습니다.");
    System.out.println("--------------------------------");
  }
}


4/4-------------------------- EchoClient.java --------------------------
import java.rmi.Naming;
import java.rmi.*;
import java.net.*;

public class EchoClient{
 public static void main(String args[]){
  String url = "rmi://127.0.0.1/Echo";
                     //String url = "rmi://" + args[0] + "/Echo";

  Echo echoRef = null;
  try{
   echoRef = (Echo)Naming.lookup(url);

   System.out.println(echoRef.sayEcho(args[0]));
  }catch(RemoteException e){
   e.printStackTrace();
  }catch(MalformedURLException e){
   e.printStackTrace();
  }catch(NotBoundException e){
   e.printStackTrace();
  }
  
 }
}

 

2. 클라이언트쪽
------------------------ EchoClientThread.java -------------------
/***********************************
파일명:
작성자: 엄기흥
최종 수정일: 20020308-2102
파일 내용: 자바 수업 중에 테스트 한 파일
************************************/
import java.rmi.Naming;
import java.rmi.*;
import java.net.*;

public class EchoClientThread extends Thread{
 String ip=null;
 Echo echoRef = null;

 EchoClientThread(String ip){
     this.ip = ip;
 }

 public void run(){
  try{
   String url = "rmi://" + ip + "/Echo";
   echoRef = (Echo)Naming.lookup(url);
   System.out.println(echoRef.sayEcho("누룽지"));

  }catch(RemoteException e){
   e.printStackTrace();
  }catch(MalformedURLException e){
   e.printStackTrace();
  }catch(NotBoundException e){
   e.printStackTrace();
  }

 }

 public static void main(String args[]){
  EchoClientThread e67, e74, e76, e78, e98, e72, e69;
  

  e67 = new EchoClientThread("211.108.242.106");
  e74 = new EchoClientThread("211.108.242.107");
  e76 = new EchoClientThread("211.108.242.109");
  e78 = new EchoClientThread("211.108.242.110");
  e98 = new EchoClientThread("211.108.242.108");
  e72 = new EchoClientThread("211.108.242.112");
  e69 = new EchoClientThread("211.108.242.114");

  e67.start();
  e74.start();
  e76.start();
  e78.start();
  e98.start();
  e72.start();
  e69.start();
 }
}

 

------------------------ EchoClientThread1.java -------------------
/***********************************
파일명:
작성자: 엄기흥
최종 수정일: 20020308-2102
파일 내용: 자바 수업 중에 테스트 한 파일
************************************/
import java.rmi.Naming;
import java.rmi.*;
import java.net.*;

public class EchoClientThread1 extends Thread{
 String ip=null;
 Echo echoRef = null;
 
 EchoClientThread1(String ip){
     this.ip = ip;
 }

 public void run(){
  try{
   if(ip.equals("67")){
    String url = "rmi://211.108.242.114/Echo";
    echoRef = (Echo)Naming.lookup(url);
    System.out.println(echoRef.sayEcho("누룽지"));
   }else if(ip.equals("74")){
    String url = "rmi://211.108.242.106/Echo";
    echoRef = (Echo)Naming.lookup(url);
    System.out.println(echoRef.sayEcho("누룽지"));
   }else if(ip.equals("76")){
    String url = "rmi://211.108.242.107/Echo";
    echoRef = (Echo)Naming.lookup(url);
    System.out.println(echoRef.sayEcho("누룽지"));
   }else if(ip.equals("78")){
    String url = "rmi://211.108.242.109/Echo";
    echoRef = (Echo)Naming.lookup(url);
    System.out.println(echoRef.sayEcho("누룽지"));
   }else if(ip.equals("98")){
    String url = "rmi://211.108.242.110/Echo";
    echoRef = (Echo)Naming.lookup(url);
    System.out.println(echoRef.sayEcho("누룽지"));
   }else if(ip.equals("72")){
    String url = "rmi://211.108.242.111/Echo";
    echoRef = (Echo)Naming.lookup(url);
    System.out.println(echoRef.sayEcho("누룽지"));
   }else if(ip.equals("69")){
    String url = "rmi://211.108.242.112/Echo";
    echoRef = (Echo)Naming.lookup(url);
    System.out.println(echoRef.sayEcho("누룽지"));
   }

  }catch(RemoteException e){
   e.printStackTrace();
  }catch(MalformedURLException e){
   e.printStackTrace();
  }catch(NotBoundException e){
   e.printStackTrace();
  }

 }

 public static void main(String args[]){
  EchoClientThread1 e67, e74, e76, e78, e98, e72, e69;
  

  e67 = new EchoClientThread1("67");
  e74 = new EchoClientThread1("74");
  e76 = new EchoClientThread1("76");
  e78 = new EchoClientThread1("78");
  e98 = new EchoClientThread1("98");
  e72 = new EchoClientThread1("72");
  e69 = new EchoClientThread1("69");

  e67.start();
  e74.start();
  e76.start();
  e78.start();
  e98.start();
  e72.start();
  e69.start();
 }
}

'java core' 카테고리의 다른 글

jdk 5.0 Annotation, Enum Test code  (0) 2005.05.11
jdk 5.0 Annotation Test Code  (0) 2005.05.11
[펌] RMI(Remote Method Invocation)  (0) 2005.05.11
jdk 5.0) In runtime, java compile.  (0) 2005.04.25
jar  (0) 2005.04.25
Runtime in jdk5.0  (0) 2005.03.26
Posted by 김용환 '김용환'

댓글을 달아 주세요