package net.sf.colossus.webserver; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.rmi.AccessException; import java.rmi.AlreadyBoundException; import java.rmi.NotBoundException; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.rmi.server.UnicastRemoteObject; import java.util.Arrays; import java.util.HashMap; import java.util.logging.Level; import java.util.logging.Logger; import net.sf.colossus.webcommon.IGameManager; import net.sf.colossus.webcommon.IManagedGame; /** This "manager" is accessible via RMI (served by the ColossusRegistry * object) for the games started in own processes. * Once a game comes up, it can register to here, telling it's game Id, * and reporting anything that happens which is of interest to the server; * for example, this could be things like player died etc. * * Additionally the server can communicate with the games, because it * gets their game Id, and looks up the ManagedGame remote object for it. * * TODO: work just started (2011-04-24) * * * @author Clemens Katzer */ public class GameManager implements IGameManager { private static final Logger LOGGER = Logger.getLogger(GameManager.class .getName()); public final static String OBJ_ID = "IGameManager"; private final HashMap<String, IManagedGame> games; private ColossusRegistry r; private Registry registry; public GameManager() { games = new HashMap<String, IManagedGame>(); LOGGER.info("List games created."); initRegistryIfNeeded(); LOGGER.info("Registry created."); doGetRegistry(); registerManager(); LOGGER.info("Game Manager <init>: registration to registry done."); listRegistryContents(); } private void initRegistryIfNeeded() { r = new ColossusRegistry(ColossusRegistry.DEFAULT_PORT); int p = r.getPort(); LOGGER.info("main: registry now running on port " + p); } private void doGetRegistry() { try { registry = LocateRegistry.getRegistry(); } catch (RemoteException e) { LOGGER.log(Level.SEVERE, "registerManager: " + e); } } public void listRegistryContents() { try { String[] list = registry.list(); System.out.println(Arrays.asList(list)); } catch (Exception e) { LOGGER.log(Level.WARNING, "list() failed: ", e); } } private void registerManager() { try { IGameManager stub = (IGameManager)UnicastRemoteObject .exportObject(this, 0); registry.bind(OBJ_ID, stub); LOGGER.info("Manager registered to registry."); } catch (RemoteException e) { System.err.println("registerManager: " + e.toString()); e.printStackTrace(); } catch (AlreadyBoundException e) { System.err.println("registerManager: " + e.toString()); e.printStackTrace(); } } public void unregisterManager() { try { registry.unbind(OBJ_ID); LOGGER.info("GameManager unregistered."); } catch (RemoteException e) { LOGGER.log(Level.SEVERE, "unregisterManager: RemoteException ", e); } catch (NotBoundException e) { LOGGER.log(Level.SEVERE, "unregisterManager: NotBound ", e); } } // Mostly useful for main() public int getGameCount() { return games.size(); } public void tellEvent(String description) throws RemoteException { System.out.println("Game told us: " + description); } public void registerGame(String gameId) throws RemoteException, NotBoundException { System.out.println("Game " + gameId + " registered on server."); IManagedGame gameStub = lookupGameByRegid(gameId); games.put(gameId, gameStub); } public void unregisterGame(String gameId) throws AccessException, NotBoundException, RemoteException { lookupGameByRegid(gameId); games.remove(gameId); } private IManagedGame lookupGameByRegid(String gameId) throws AccessException, NotBoundException, RemoteException { IManagedGame game = null; game = (IManagedGame)registry.lookup(gameId); String status = game.tellStatus(); System.out.println("Got Status from game " + gameId + ": '" + status + "'"); return game; } /** * This is only for testing purposes. * Normally the GameManager object is created by WebServer object. */ public static void main(String[] args) { final GameManager gm = new GameManager(); Runnable runny = new Runnable() { public void run() { exitOnReturn(gm); } }; new Thread(runny).start(); while (true) { int count = gm.getGameCount(); System.out.println("Game count: " + count); sleepFor(5000); } } // Helper for main() private static void sleepFor(long millis) { try { Thread.sleep(millis); } catch (InterruptedException e) { LOGGER.log(Level.FINEST, "InterruptException caught... ignoring it..."); } } // Helper for main() private static void exitOnReturn(GameManager gm) { try { BufferedReader reader = new BufferedReader(new InputStreamReader( System.in)); String textLine = reader.readLine(); System.out.println("Got line: " + textLine); gm.unregisterManager(); System.exit(0); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }