키보드로부터 입력된 문자열이 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();
}
}
}