이전 포스팅에서 말했듯이 이번에는 간단히 RMI를 구현해 보도록 하겠다.
Remind하는 차원에서 RMI의 작성순서를 생각해 보면,
1. 인터페이스 작성
2. 서비스 해줄 class작성
3. 서버 프로그램 작성
4. 클라이언트 프로그램 작성
5. 1~4 컴파일
6. rmic.exe를 이용해 stub 생성 : ex) rmic HelloImpl
7. start rmiregistry 포트번호 : 대게 기본으로 1099를 쓴다.
8. start 3번 프로그램 실행 : 예) start java HelloServer
9. 클라이언트 프로그램 실행 : 예) java HelloClient
---------------------------------------------------------
그럼 지금부터 본격적으로 RMI를 구현해 보자.
우선 생성할 파일들의 이름을 나열해 보자.
인터페이스 : Hello.java
서비스해줄 class : HelloImpl.java
서버 프로그램 : HelloServer.java
클라이언트 프로그램 : HelloClient.java
첫번째로 인터페이스를 구현한다.
java.rmi.RemoteException
//원격 인터페이스를 만들기 위해 Remote interface를 상속받아야 한다.
//원격 인터페이스를 만들기 위해 Remote interface를 상속받아야 한다.
public interface Hello extends Remote{
public String sayHello(String name) throws RemoteException;
}
두번째로 서비스 해줄 클래스를 구현한다.
import java.rmi.Naming;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.RemoteException;
public class HelloImpl extends UnicastRemoteObject implements Hello{
//기본 생성자 호출...안해줘도 되는데..ㅡㅡ;;;
public HelloImpl() throws RemoteException{
super();
}
import java.rmi.server.UnicastRemoteObject;
import java.rmi.RemoteException;
public class HelloImpl extends UnicastRemoteObject implements Hello{
//기본 생성자 호출...안해줘도 되는데..ㅡㅡ;;;
public HelloImpl() throws RemoteException{
super();
}
public String sayHello(String name){
return "Hello RMI "+name+"!!";
}
}
return "Hello RMI "+name+"!!";
}
}
세번째로 서버 프로그램을 구현한다.
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.net.MalformedURLException;
public class HelloServer{
public static void main(String[] args){
try{
HelloImpl remObj = new HelloImpl();
//매개변수로 (url, 원격객체)가 들어간다.
import java.rmi.RemoteException;
import java.net.MalformedURLException;
public class HelloServer{
public static void main(String[] args){
try{
HelloImpl remObj = new HelloImpl();
//매개변수로 (url, 원격객체)가 들어간다.
Naming.rebind("rmi://localhost:1099/HelloRemote", remObj);
System.out.println("HelloRemote객체에 대한 레지스트리 등록후 클라이언트 호출 대기");
}catch(RemoteException e){
System.out.println("원격 객체 처리과정에 에러 발생");
}catch(MalformedURLException e){
System.out.println("URL문자열 에러!!!");
}
}
}
System.out.println("HelloRemote객체에 대한 레지스트리 등록후 클라이언트 호출 대기");
}catch(RemoteException e){
System.out.println("원격 객체 처리과정에 에러 발생");
}catch(MalformedURLException e){
System.out.println("URL문자열 에러!!!");
}
}
}
네번째로 클라이언트 프로그램을 작성한다.
import java.rmi.*;
import java.net.MalformedURLException;
public class HelloClient
{
public static void main(String[] args){
try{
//lookup의 return type은 remote이다.
//따라서 remote를 상속받는 Hello가 반환된다.
//그래서 반환받는 값으로 Object타입이나 Hello타입으로 반환 받으면 된다.
Object obj = Naming.lookup("rmi://localhost:1099/HelloRemote");
Hello h = (Hello)obj;
String msg = h.sayHello("bbbb");
System.out.println("Hello 원격 객체로부터 받은 메세지:["+msg+"]");
}catch(RemoteException e){
System.out.println("원격 메소드 호출 실패");
}catch(NotBoundException e){
System.out.println("바운딩 실패 :"+e.getMessage());
}catch(MalformedURLException e){
System.out.println("잘못된 URL 문자열");
}
}
}
import java.net.MalformedURLException;
public class HelloClient
{
public static void main(String[] args){
try{
//lookup의 return type은 remote이다.
//따라서 remote를 상속받는 Hello가 반환된다.
//그래서 반환받는 값으로 Object타입이나 Hello타입으로 반환 받으면 된다.
Object obj = Naming.lookup("rmi://localhost:1099/HelloRemote");
Hello h = (Hello)obj;
String msg = h.sayHello("bbbb");
System.out.println("Hello 원격 객체로부터 받은 메세지:["+msg+"]");
}catch(RemoteException e){
System.out.println("원격 메소드 호출 실패");
}catch(NotBoundException e){
System.out.println("바운딩 실패 :"+e.getMessage());
}catch(MalformedURLException e){
System.out.println("잘못된 URL 문자열");
}
}
}
다섯번째로 위에 작성한 파일들을 컴파일 한다.
->src\package명\*.java 파일들을 모두 컴파일 한다. (javac -d . *.java)

여섯번째로 rmic.exe를 이용해 stub을 생성한다.


stub가 생성된 것을 확인할 수 있다.
일곱번째로, rmiregistry를 등록한다.


위와 같이 rmiregistry를 등록하면 빈 cmd창이 열린다. 닫으면 안된다.
여덟번째로 서버를 실행시킨다.
->bin\ 에서 start 한다


위와 같이 새로운 cmd창이 뜬다. 닫으면 안된다.
아홉번째로 client프로그램을 실행시켜서 테스트 해본다.

위와 같이 메시지가 출력되는 것을 볼 수 있다.
이상으로 간단하게 RMI를 구현해 보았다.
참고로, 구현하면서 사용한 인터페이스, 클래스에 대해 간단히 설명하겠다.
<Remote 인터페이스>
- Remote 객체
∙ 서버 측에 존재하며 실제 호출되는 method를 정의하고 있는 객체는 반드시 이 interface를 구현해야 한다.
∙ 원격지의 객체들을 RMI시스템 상에서 구분하는데 사용
∙ 이 인터페이스에 정의되어 있는 method들만이 원격지에서 호출된다.
주의) 선언되는 method는 반드시 RemoteException을 처리해야 한다.
<UnicastRemoteObject 클래스>
- RemoteServer 클래스를 상속받는 클래스.
- 자신의 생성자에게 원격 객체를 등록하는 기능을 정의
∙ 원격 객체를 생성하고 노출시켜주어 client가 method를 호출할 수 있도록 도와주는 클래스
∙ 이 클래스를 상속받은 원격 객체는 원격 객체가 메모리에 상주해 있는 동안에만 client로부터 method 호출을 받을 수 있다.
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
댓글 없음:
댓글 쓰기