▣ 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
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 '김용환'
,