äŸãšããŠãã²ãŒã ãRock-Paper-Scissorsãã®ãªã³ã©ã€ã³å®è£ ãäœæããããšã決å®ãããŸããã
ãã®èšäºã§ã¯ããµãŒããŒãäœæããŠèµ·åããããšããŸãã 次ã®èšäºã§ã¯ããã®ãµãŒããŒçšã®å°ããªã¯ã©ã€ã¢ã³ããäœæãããã®ããã©ãŒãã³ã¹ã確èªããŸãã
ä»äºã®æºå
ãŸãããããã sgs-server-dist-0.10.2.zipã¢ãŒã«ã€ãã«ããReddwarfãµãŒããŒãããŠã³ããŒãããsgs-server-dist-0.10.2ãã©ã«ããŒã«ã³ã³ãã³ãã解åããå¿ èŠããããŸãã
ãããžã§ã¯ãäœæ
ãæ°ã«å ¥ãã®éçºç°å¢ã§ãããžã§ã¯ããäœæããŸãã
ãããžã§ã¯ãã¯ã·ã³ãã«ã«ãªããããMavenã¯äœ¿çšããŸããã
éçºã«ã¯ãsgs-server-dist-0.10.2 \ lib \ãã£ã¬ã¯ããªã«ããsgs-server-api-0.10.2.jarã©ã€ãã©ãªãå¿ èŠã§ã
META-INFãã©ã«ããŒãäœæããŸããããã«ã¯ããããã§ã¹ããã¡ã€ã«MANIFEST.MFãå«ãŸããŠããå¿ èŠããããŸãã ããããªããšããã©ãããã©ãŒã ã¯ãããžã§ã¯ãjarãã¡ã€ã«ã§ã®äœæ¥ãæåŠããŸãã ç§ã®ãã¡ã€ã«ã«ã¯1è¡ããå«ãŸããŠããŸããïŒ
ãããã§ã¹ãããŒãžã§ã³ïŒ1.0
ãŸããMETA-INFãã©ã«ããŒã«app.propertiesãã¡ã€ã«ãäœæããå¿ èŠããããŸãã ãã®ãã¡ã€ã«ã«ã¯ããµãŒããŒã®èµ·åèšå®ãå«ãŸããŠããŸãã ãããžã§ã¯ãã®å Žåããã¡ã€ã«ã«ã¯æ¬¡ã®ããããã£ãå«ãŸããŠããŸãã
# . com.sun.sgs.app.name=RockPaperScissors # , AppListener com.sun.sgs.app.listener=hello.reddwarf.server.Server # , com.sun.sgs.app.root=data
ããã¯ãæäœéå¿ èŠãªãªãã·ã§ã³ã®ã»ããã§ãã éçºäžã«ã次ã®ããããã£ãåŒãç¶ãæçšãªå ŽåããããŸãã
- com.sun.sgs.impl.transport.tcp.listen.port-ãµãŒããŒããªãã¹ã³ããããŒãïŒããã©ã«ãã§ã¯62964ïŒ
- com.sun.sgs.app.authenticators-èªèšŒãæ åœããã¯ã©ã¹ã®ååïŒèªèšŒããã»ã¹ã¯ã²ãŒã ããžãã¯ããåé€ãããç¬ç«ããã¢ãžã¥ãŒã«ãšããŠäœ¿çšã§ããŸãïŒ
- com.sun.sgs.impl.service.session.allow.new.login-å¥ã®ã¯ã©ã€ã¢ã³ãããæ¥ç¶ããããã¬ãŒã€ãŒãæ¥ç¶ã§ããããã«ãããã©ããã trueã®å Žåãã²ãŒã å ã«ãã人ãã¹ããŒããŸãã falseã®å Žåãå¥ã®ã¯ã©ã€ã¢ã³ãããã®æ¥ç¶ãèš±å¯ããŸããã
ãã®ä»ã®ããããã£ã®è©³çŽ°ã«ã€ããŠã¯ã ããã¥ã¡ã³ããã芧ãã ããã
ã²ãŒã ã¢ãŒããã¯ãã£
ã²ãŒã ã«ã¯æ¬¡ã®ãšã³ãã£ãã£ãå¿ èŠã§ãã
ãµãŒã㌠-ãã¬ã€ã€ãŒã®ãªã¹ãããªã³ã©ã€ã³ã§ä¿åããæ¥ç¶ã®åŠçãåŠçããã¯ã©ã¹ã
ãã¬ãŒã€ãŒ - ãã¬ãŒã€ãŒãè¡šããŸãã ãã¬ã€ã€ãŒã«ã¯æ¬¡ã®å±æ§ããããŸãïŒååïŒåããã°ã€ã³ïŒãšãã€ã³ãæ°ã æŠéã«åå ã§ããŸãã
ããã« -ããã«ã§ãã ãã®ãªããžã§ã¯ãã§ã¯ããã¬ãŒã€ãŒã®å¿çãåŸ ã£ãŠåè ã決å®ããŸãã 2人ã®ãã¬ãŒã€ãŒãžã®ãªã³ã¯ãå«ãŸããŠããŸãã
æŠåšã¯ãçŽæ¥ç³ãã¯ãã¿ãçŽãªã©ã®æŠåšã®åçŽãªåæã§ãã
ã¯ã©ã¹å³ã®åœ¢åŒã§æãããŠããå Žåã次ã®ããšãããããŸãã
ãã¹ãŠã®ã²ãŒã ãšã³ãã£ãã£ïŒæŠåšãé€ãïŒã¯ããµãŒããŒã®å®è¡äžã«ãã©ã³ã¶ã¯ã·ã§ã³æ§ãæäŸããå éšããŒã¿ããŒã¹ã«æ ŒçŽãããçžäºã«åç §ãããããjava.io.Serializableããã³com.sun.sgs.app.ManagedObjectã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ããå¿ èŠããããŸãã
ãµãŒããŒã¯ã©ã¹ã ãã¬ãŒã€ãŒã®åæåãšæ¥ç¶
Serverã¯ã©ã¹ã¯ãµãŒããŒã®èµ·åãã€ã³ãã§ãããããcom.sun.sgs.app.AppListenerã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ããå¿ èŠããããŸãã
void initialize(Properties props)
ã¯ããµãŒããŒã®æåã®èµ·åæã«åŒã³åºãããŸãã äœæ¥ã«å¿ èŠãªåæå€ã§å éšããŒã¿ããŒã¹ãæºãããŸãã éèŠãªæ©èœïŒãµãŒããŒãåæ¢ïŒãŸãã¯åŒ·å¶çµäºïŒããŠããåèµ·åããå Žåããã®ã¡ãœããã¯åŒã³åºãããŸããã å éšããŒã¿ããŒã¹ã¯ãµãŒããŒãèµ·åãããŸã§ä¿åãããåæ¢ããç¬éããäœæ¥ãç¶ããããšãã§ããŸãã
ClientSessionListener loggedIn(ClientSession session)
ã¯ãèªèšŒãæåããåŸã«åŒã³åºããããã¬ãŒã€ãŒãè¡šããªããžã§ã¯ããè¿ãå¿ èŠããããŸãã ãã®äŸã§ã¯ãããã¯Playerã«ãªããŸãã
ãµãŒããŒã«æ¥ç¶ãããŠãããã¹ãŠã®ãã¬ãŒã€ãŒã¯ãç¹å¥ãªã³ã¬ã¯ã·ã§ã³ã«ä¿åãããŸãã Reddwarfã«ã¯ãã²ãŒã ãšã³ãã£ãã£çšã®ScalableHashMapã®ç¹å¥ãªã³ã¬ã¯ã·ã§ã³ããããŸãã ãã®ã³ã¬ã¯ã·ã§ã³ã®å©ç¹ã¯ãå€æŽããããšãå®å šã«ã§ã¯ãªãéšåçã«ãããã¯ãããããšã§ãïŒå éšããŒã¿ããŒã¹ã®ããã¯ãæå³ããŸãïŒã ãŸããServerãªããžã§ã¯ãã§ã¯ãã³ã¬ã¯ã·ã§ã³èªäœã§ã¯ãªããã³ã¬ã¯ã·ã§ã³ãžã®ãªã³ã¯ïŒManagedReferenceïŒãä¿åããŸãã
èšèããè¡çºã«ç§»ããšã次ã®ã³ãŒããåŸãããŸãã
package hello.reddwarf.server; import java.io.Serializable; import com.sun.sgs.app.*; import com.sun.sgs.app.util.ScalableHashMap; import java.util.Properties; /** * . , * . */ public class Server implements AppListener, Serializable, ManagedObject { public ManagedReference<ScalableHashMap<String, Player>> onlinePlayersRef; @Override public void initialize(Properties props) { // ScalableHashMap<String, Player> onlinePlayers = new ScalableHashMap<String, Player>(); onlinePlayersRef = AppContext.getDataManager().createReference(onlinePlayers); } @Override public ClientSessionListener loggedIn(ClientSession session) { String name = session.getName(); // . , Player player = loadOrRegister(name); // . - , // - player.setSession(session); // , player.connected(); // - onlinePlayersRef.get().put(player.name, player); return player; } }
ããŒã¿ããŒã¹ãæäœããã«ã¯ãDataManagerã䜿çšããŸããããã«ãããããŒã¿ããŒã¹ãžã®æžã蟌ã¿ãããŒã¿ããŒã¹ããã®èªã¿åããManagedReferenceãªã³ã¯ã®äœæãå¯èœã«ãªããŸãã ããŒã¿ããŒã¹ã¯ããŒãšå€ã®ã¹ãã¬ãŒãžã§ããããããplayerããšãããã¬ãã£ãã¯ã¹ã®ä»ãããã¬ãŒã€ãŒã®ååãããŒãšããŠäœ¿çšãããPlayerãªããžã§ã¯ãå šäœãå€ã«ã·ãªã¢ã«åãããŸãã ããŒã¹ãããã¬ãŒã€ãŒãããŒãããé¢æ°ãäœæããŸãïŒãã¬ãŒã€ãŒãããŒã¿ããŒã¹ã«èŠã€ãããªãå Žåã¯äœæããŸãïŒã
private Player loadOrRegister(String name) { try { return (Player) AppContext.getDataManager().getBindingForUpdate("player." + name); } catch (NameNotBoundException e) { // - // , Player player = new Player(name, this); AppContext.getDataManager().setBinding("player." + name, player); return player; } }
ãã¬ãŒã€ãŒã®ã¯ã©ã¹ãšãããã³ã«
次ã¯Playerã¯ã©ã¹ãäœæããçªã§ãã ãã®ã¯ã©ã¹ã¯ãã¬ãŒã€ãŒãè¡šãããã©ãããã©ãŒã ããçä¿¡ã¡ãã»ãŒãžã®éç¥ãåãåããŸãã ããã§ã¯ããããã³ã«ã«ã€ããŠè©±ããŸãããã Reddwarfã䜿çšãããšãçä¿¡ããã³çºä¿¡ã¡ãã»ãŒãžããã€ãã®é åãšããŠåŠçã§ãããããã³ã«ã®å®è£ ã¯ã²ãŒã éçºè ã®è£éã«ä»»ãããŸãã ã²ãŒã ãããããããã§ã¯ãåçŽãªããã¹ããããã³ã«ã䜿çšããŸãã
ïŒ server- > clientïŒ SCORE <number> -ãµãŒããŒã¯ãã¬ã€ã€ãŒã«ãã€ã³ãæ°ãäŒããŸã
ïŒã¯ã©ã€ã¢ã³ã->ãµãŒããŒïŒ PLAY-ã²ãŒã ãéå§ããããã®ãã¬ãŒã€ãŒã®ãªã¯ãšã¹ã
ïŒãµãŒããŒ->ã¯ã©ã€ã¢ã³ãïŒ BATLE <åå> -æå®ããããã¬ã€ã€ãŒãšã®æŠããå§ãŸããŸãã
ïŒãµãŒããŒ->ã¯ã©ã€ã¢ã³ãïŒ ãšã©ãŒ -æŠéã®ãã¬ã€ã€ãŒãèŠã€ãããŸããã§ããïŒãµãŒããŒã«èª°ãããªããããã¹ãŠã®æŠéã«åå ããŠããŸããïŒ
ïŒã¯ã©ã€ã¢ã³ã->ãµãŒããŒïŒ ROCK-ãã¬ã€ã€ãŒã¯ãStoneããšèšããŸã
ïŒã¯ã©ã€ã¢ã³ã->ãµãŒããŒïŒ SCISSORS-ãã¬ã€ã€ãŒã¯ãã¯ãã¿ããšèšããŸã
ïŒã¯ã©ã€ã¢ã³ã->ãµãŒããŒïŒ çŽ -ãã¬ã€ã€ãŒã¯ãçŽããšèšããŸã
ïŒãµãŒããŒ->ã¯ã©ã€ã¢ã³ãïŒ DRAW-æç»
ïŒãµãŒããŒ->ã¯ã©ã€ã¢ã³ãïŒ WON-ãã¬ãŒã€ãŒãåã¡ãŸãã
ïŒãµãŒããŒ->ã¯ã©ã€ã¢ã³ãïŒ LOST-ãã¬ã€ã€ãŒã倱ãããŸãã
ãããã³ã«ããããã¬ãŒã€ãŒã®ã¢ã¯ã·ã§ã³ãšæ©èœã®ã·ãŒã±ã³ã¹ãç解ã§ãããããããã«ã€ããŠåå¥ã«èª¬æããããšã¯ããŸããã
ãã®ã³ãŒãã䜿çšããŠãããã¹ãããã€ãã«ãšã³ã³ãŒããããããã®éãè¡ãããšãã§ããŸãã
package hello.reddwarf.server; import java.nio.ByteBuffer; public class Messages { public static ByteBuffer encodeString(String s) { return ByteBuffer.wrap(s.getBytes()); } public static String decodeString(ByteBuffer message) { byte[] bytes = new byte[message.remaining()]; message.get(bytes); return new String(bytes); } }
次ã«ããã¬ãŒã€ãŒã®ãªããžã§ã¯ãã®äœæã«é²ã¿ãŸãã
ãã¬ãŒã€ãŒã¯æ¬¡ã®ãã£ãŒã«ããä¿æããŸãã
- å
- ç¹æ°
- ãµãŒããŒãªã³ã¯ïŒãªã³ã©ã€ã³ãã¬ãŒã€ãŒã®ãªã¹ãã«ã¢ã¯ã»ã¹ããããïŒ
- ã»ãã·ã§ã³ãžã®ãªã³ã¯ïŒã¯ã©ã€ã¢ã³ãã«ã¡ãã»ãŒãžãéä¿¡ããããïŒ
- æŠéãžã®ãªã³ã¯ïŒãã¬ã€ã€ãŒãæŠéäžã®å Žåãããã§ãªãå Žåã¯nullïŒ
package hello.reddwarf.server; import com.sun.sgs.app.*; import com.sun.sgs.app.util.ScalableHashMap; import java.io.Serializable; import java.nio.ByteBuffer; import java.util.*; public class Player implements Serializable, ManagedObject, ClientSessionListener { private final static Random random = new Random(); public final String name; private int score; // , private ManagedReference<ClientSession> sessionRef; // - private ManagedReference<Server> serverRef; // . - null private ManagedReference<Battle> battleRef; public Player(String name, Server server) { this.name = name; serverRef = AppContext.getDataManager().createReference(server); score = 0; } @Override public void receivedMessage(ByteBuffer byteBuffer) { // String message = Messages.decodeString(byteBuffer); if (message.equals("PLAY")) { play(); } else if (message.equals("ROCK")) { answer(Weapon.ROCK); } else if (message.equals("PAPER")) { answer(Weapon.PAPER); } else if (message.equals("SCISSORS")) { answer(Weapon.SCISSORS); } } @Override public void disconnected(boolean b) { serverRef.get().disconnect(this); } private void answer(Weapon weapon) { if (battleRef != null) { battleRef.getForUpdate().answer(this, weapon); } } private void play() { logger.info("Choosing enemy for "+name); // Player target = getRandomPlayer(); if (target != null && target.battleRef == null) { Battle battle = new Battle(this, target); this.sessionRef.get().send(Messages.encodeString("BATTLE " + target.name)); target.sessionRef.get().send(Messages.encodeString("BATTLE " + this.name)); target.battleRef = AppContext.getDataManager().createReference(battle); this.battleRef = target.battleRef; battle.start(); } else { this.sessionRef.get().send(Messages.encodeString("ERROR")); } } /** * ( ) * , null * @return null, */ private Player getRandomPlayer() { ScalableHashMap<String,Player> onlineMap = serverRef.get().onlinePlayersRef.get(); Set<String> namesSet = new HashSet<String>(onlineMap.keySet()); namesSet.remove(name); if (namesSet.isEmpty()) { return null; } else { ArrayList<String> namesList = new ArrayList<String>(namesSet); String randomName = namesList.get(random.nextInt(namesList.size())); return onlineMap.get(randomName); } } public void connected() { // , sessionRef.get().send(Messages.encodeString("SCORE " + score)); } /** * , */ public void battleResult(Battle.Result result) { switch (result) { case DRAW: score+=1; sessionRef.get().send(Messages.encodeString("DRAW")); break; case WON: score+=2; sessionRef.get().send(Messages.encodeString("WON")); break; case LOST: sessionRef.get().send(Messages.encodeString("LOST")); break; } sessionRef.get().send(Messages.encodeString("SCORE " + score)); battleRef = null; } public void setSession(ClientSession session) { sessionRef = AppContext.getDataManager().createReference(session); } }
æŠåšããã³æŠéã¯ã©ã¹
æŠåšã®åæã¯éåžžã«åçŽã§ãããã³ã¡ã³ãã¯äžèŠã§ãã
package hello.reddwarf.server; public enum Weapon { ROCK, PAPER, SCISSORS; boolean beats(Weapon other) { return other != null && this != other && this.ordinal() == (other.ordinal() + 1) % values().length; } }
æŠãã«ç§»ããŸãã
æŠéã«ã¯äžæã®èå¥åãããã2人ã®ãã¬ã€ã€ãŒãžã®ãªã³ã¯ããã®åçãããã³ã¢ã¯ãã£ããã£ãã©ã°ãå«ãŸããŠããŸãã
æŠéãäœæããããšãå¥ã®ã¿ã¹ã¯ãèµ·åããã5ç§ã§æŠéãå®äºããŸãã
ãã®æéãçµéãããšãæŠéã®çµæãåèšãããŸãã ãã¬ã€ã€ãŒã®1人ã ããçããåºããå Žåãäž¡æ¹ã®å Žåãåè ãšèŠãªãããŸã-åè ã¯éåžžã®èŠåãããããããã«åŸã£ãŠæ±ºå®ãããŸãã
ã¿ã¹ã¯ã¯ãAppContext.getTaskManagerïŒïŒã䜿çšããŠååŸã§ããTaskManagerãµãŒãã¹ã䜿çšããŠå®è¡ãããŸãã ãã®ãããŒãžã£ãŒã䜿çšãããšãåå¥ã®ãã©ã³ã¶ã¯ã·ã§ã³ã§å®è¡ãããã¿ã¹ã¯ãããã«å®è¡ããããæå®ããæéã®åŸã«å®è¡ããããå®æçã«å®è¡ã§ããŸãã äºæ³ã©ããããã¹ãŠã®ã¿ã¹ã¯ã¯å éšããŒã¿ããŒã¹ã«ãä¿åãããŸããã€ãŸãããµãŒããŒã®åèµ·ååŸã«å®è¡ãããŸãã
ãããã£ãŠãã¯ã©ã¹ã³ãŒãã¯Battleã§ãã
package hello.reddwarf.server; import com.sun.sgs.app.AppContext; import com.sun.sgs.app.ManagedObject; import com.sun.sgs.app.ManagedReference; import com.sun.sgs.app.Task; import java.io.Serializable; import java.util.concurrent.atomic.AtomicInteger; public class Battle implements ManagedObject, Serializable { // 5 private static final long BATTLE_TIME_MS = 5000; enum Result { DRAW, WON, LOST } private boolean active; private ManagedReference<Player> starterPlayerRef; private ManagedReference<Player> invitedPlayerRef; private Weapon starterWeapon = null; private Weapon invitedWeapon = null; public Battle(Player starterPlayer, Player invitedPlayer) { starterPlayerRef = AppContext.getDataManager().createReference(starterPlayer); invitedPlayerRef = AppContext.getDataManager().createReference(invitedPlayer); active = false; } /** * . * , BATTLE_TIME_MS . */ public void start(){ active = true; AppContext.getTaskManager().scheduleTask(new BattleTimeout(this), BATTLE_TIME_MS); } /** * . * , . * @param player - * @param weapon - */ public void answer(Player player, Weapon weapon){ if (active) { if (player.name.equals(starterPlayerRef.get().name)) { starterWeapon = weapon; } else { invitedWeapon = weapon; } } } /** * . * . */ private void finish() { active = false; Player starterPlayer = starterPlayerRef.getForUpdate(); Player invitedPlayer = invitedPlayerRef.getForUpdate(); if (starterWeapon != null && starterWeapon.beats(invitedWeapon)) { starterPlayer.battleResult(Result.WON); invitedPlayer.battleResult(Result.LOST); } else if (invitedWeapon != null && invitedWeapon.beats(starterWeapon)) { invitedPlayer.battleResult(Result.WON); starterPlayer.battleResult(Result.LOST); } else { starterPlayer.battleResult(Result.DRAW); invitedPlayer.battleResult(Result.DRAW); } AppContext.getDataManager().removeObject(this); } /** * , . */ private static class BattleTimeout implements Serializable, Task { private ManagedReference<Battle> battleRef; public BattleTimeout(Battle battle) { battleRef = AppContext.getDataManager().createReference(battle); } @Override public void run() throws Exception { battleRef.getForUpdate().finish(); } } }
ãã®ã³ãŒããèªããšããå éšBattleTimeoutã¯ã©ã¹ãéçã«ãªããããã«ãžã®ãªã³ã¯ãæ瀺çã«ä¿åããã®ã¯ãªãã§ããïŒ ééçãšããŠå®£èšããããã«ãã£ãŒã«ãã«çŽæ¥ã¢ã¯ã»ã¹ã§ããŸããã
å®éãééçå éšã¯ã©ã¹ã¯èŠªããã«ãžã®ãªã³ã¯ãæé»çãªåœ¢åŒã§ä¿åãããããä»ããŠããã«ã«ã¢ã¯ã»ã¹ããŸãã ãã ããReddwarfãã©ãããã©ãŒã ïŒãã©ã³ã¶ã¯ã·ã§ã³ïŒã®æ©èœã¯ãå¥ã®ãã©ã³ã¶ã¯ã·ã§ã³ããManagedObjectïŒBattleïŒã«çŽæ¥ã¢ã¯ã»ã¹ããããšãçŠæ¢ããŠããŸãããã®å ŽåãäŸå€ãã¹ããŒãããŸãã å¥ã®ãã©ã³ã¶ã¯ã·ã§ã³å ã®ãªããžã§ã¯ããžã®çŽæ¥åç §ã¯æ£ãããããŸããã éçãªå éšã¯ã©ã¹ã®ã¿ã䜿çšãããšãããã©ãããã©ãŒã äœæè ã®æšå¥šäºé ã¯ãããã«é¢é£ããŠããŸãã
ãŸããåç §ã«ãã管ç察象ãªããžã§ã¯ãã®åä¿¡ã«æ³šæããããšæããŸãã
ManagedReferenceã®äžèšã®ã³ãŒãã¯ãgetïŒïŒã¡ãœãããšgetForUpdateïŒïŒã®äž¡æ¹ã䜿çšããŸãã
ååãšããŠãgetïŒïŒã®ã¿ã䜿çšã§ããŸãã getForUpdateïŒïŒã䜿çšãããšããµãŒããŒã¯ããã©ã³ã¶ã¯ã·ã§ã³ãå®äºããåã«ã©ã®ãªããžã§ã¯ããå€æŽãããããç¥ãã競åãããã©ã³ã¶ã¯ã·ã§ã³ãæ€åºãããå Žåãå°ãåã«ã¿ã¹ã¯ããã£ã³ã»ã«ã§ããŸãã ããã«ãããgetïŒïŒã䜿çšããå Žåã«æ¯ã¹ãŠé床ãããããåäžããŸãã
æåŸã«ããµãŒããŒã®æºåãã»ãŒæŽããŸããã
ãã®ã³ã°ãå°ãè¿œå ãïŒç°¡åã«ããããã«java.util.loggingã䜿çšããŸãïŒããããžã§ã¯ãããã«ãã§ããŸãã
ã¢ã»ã³ããªã®çµæãšããŠãjarãã¡ã€ã«ãããšãã°deploy.jarãååŸããå¿ èŠããããŸãã
ããããã¹ãŠãæåã§åéããããªãå Žåã¯ãå®æããdeploy.jarãã¡ã€ã«ãããããååŸã§ããŸã ã
ãã®ãã¡ã€ã«ã¯sgs-server-dist-0.10.2 \ distã«é 眮ããå¿ èŠããããŸãã
sgs-server-dist-0.10.2ãã£ã¬ã¯ããªã«ç§»åãããã次ã®ã³ãã³ããå®è¡ããŸãã
java -jar bin/sgs-boot.jar
ãã®çµæãã³ã³ãœãŒã«ã«æ¬¡ã®ããã«è¡šç€ºãããŸãã
02, 2012 9:45:19 PM com.sun.sgs.impl.kernel.Kernel <init> INFO: The Kernel is ready, version: 0.10.2.1 02, 2012 9:45:19 PM com.sun.sgs.impl.service.data.store.DataStoreImpl <init> INFO: Creating database directory : C:\sgs-server-dist-0.10.2.1\data\dsdb 02, 2012 9:45:19 PM com.sun.sgs.impl.service.watchdog.WatchdogServerImpl registerNode INFO: node:com.sun.sgs.impl.service.watchdog.NodeImpl[1,health:GREEN,backup:(none)]@black registered 02, 2012 9:45:19 PM hello.reddwarf.server.Server initialize INFO: Starting new Rock-Paper-Scissors Server. Initialized database. 02, 2012 9:45:19 PM com.sun.sgs.impl.kernel.Kernel startApplication INFO: RockPaperScissors: application is ready
ãã£ãïŒ ãµãŒããŒãèµ·åããŸããïŒ ããã§ãã¯ã©ã€ã¢ã³ãã«å¯ŸåŠã§ããŸãã
Rock-Paper-Paperãªã³ã©ã€ã³ã²ãŒã ã®äŸã䜿çšããReddwarfïŒClient
åç §è³æ
ãµãŒããŒAPI Javadoc
ã³ãã¥ããã£ããã¥ã¡ã³ã
ãããžã§ã¯ããã©ãŒã©ã