본문 바로가기

Java SE/RMI Callback 02

RMI Callback 02

키보드로부터 입력된 문자열이 RMI 서버에 접속한 모든 클라이언트에게 전달되도록 한다.

서버측 원격인터페이스

import java.rmi.*;

public interface ChatServer extends Remote {

 void registerClient(ClientRemote client)  throws RemoteException;
 void broadcast(String msg) throws RemoteException;
}


서버측 구현클래스

import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.RMISecurityManager;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.registry.*;
import java.util.*;

public class ChatServerImpl extends UnicastRemoteObject implements ChatServer {

 // 클라이언트의 레퍼런스를 저장해 둘 벡터
 private static Vector<ClientRemote> v = new Vector<ClientRemote>();

 public ChatServerImpl() throws RemoteException {}

 public void registerClient(ClientRemote client)  throws RemoteException {
  //client.printDate(new java.util.Date());  //클라이언트측에 있는 콜백메소드를 서버에서 호출

  // 클라이언트 레퍼런스를 벡터에 저장함
  v.add(client);
  System.out.println("인원수:"+v.size());
 }

 public void broadcast(String msg) throws RemoteException {
  for(int i=0;i<v.size();i++) {
   v.get(i).getMsg(msg);
  }
 }
 
 public static void main(String args[]) {
  try {
  ChatServerImpl obj = new ChatServerImpl();

  // 다음 라인을 실행하기 위해서는 rmiregistry.exe 를 먼저 실행해야 한다.
  //Naming.rebind("DateServer", obj);

  // rmiregistry.exe를 직접실행하지 않고 아래처럼 코드상에서 할 수 있다.
  Registry registry = LocateRegistry.createRegistry(1066); // default:1099
  registry.rebind("ChatServer", obj);

  System.out.println("HelloServer bound in registry");

  } catch (Exception e) {

      System.out.println("HelloImpl err: " + e.getMessage());

      e.printStackTrace();

  }
 }
}



클라이언트측 원격인터페이스

import java.rmi.*;

public interface ClientRemote extends Remote {

 // 서버에서 호출가능한 callback메소드 선언
 public void getMsg(String msg)  throws RemoteException;
}



클라이언트측 구현 클래스

import java.rmi.*;
import java.rmi.server.*;
import java.io.*;

public class ChatClient implements ClientRemote {

  // callback 메소드 (서버에서 호출하여 사용가능한 클라이언트 메소드)
 public void getMsg(String msg) {
  System.out.println(msg);
  System.out.println();
 }

 public static void main(String[] args) throws Exception {
    try {
  ChatServer obj = (ChatServer)Naming.lookup("rmi://localhost:1066/ChatServer");
  // default(1099)일경우 포트를 명시할 필요없음)

  ChatClient client = new ChatClient();

  //Exports the remote object to make it available to receive incoming calls using an anonymous port.
  // RMI Registry에 바인딩해서 오브젝트를 찾는 방식이 아니라 오브젝트를 서버에 직접 전달하여
  // 메소드호출을 받는 경우이므로 다음과 같이 설정한다
  // 클라이언트 오브젝트를 외부로 내 보기위한 설정
  UnicastRemoteObject.exportObject(client);

  // 클라이언트를 내 보낸다
  obj.registerClient(client);

  //obj.broadcast("안녕하세요?");
  // 키보드에서 입력된 문자열을 서버로 전송한다.
  BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  String line = null;
  System.out.print("입력: ");

  while((line=br.readLine())!=null) {
   obj.broadcast(line);
   System.out.print("입력");
  }

    } catch (Exception e) {

      System.out.println(e.getMessage());

      e.printStackTrace();

    }
  }
}