登录RMI服务器

时间:2015-05-29 21:22:13

标签: java rmi

我正在尝试实现一个可以通过RMI在网络上播放的2人游戏。我有一个Game接口和一个实现接口的GameImpl类。为了让客户端玩一个游戏,我有一个服务器类,如下所示:

public class RMIServer {

    public RMIServer(int port) throws RemoteException, AlreadyBoundException {
        Registry registry = LocateRegistry.createRegistry(port);
        Game game = new GameImpl();
        registry.bind("Game", game);
    }

    public static void main(String[] args) throws RemoteException, AlreadyBoundException {
        RMIServer server = new RMIServer(1099);
    }

}

另一方面,客户端类看起来如下:

public class RMIClient {

    RMIClient(String host, int port) throws RemoteException, NotBoundException {
        Registry registry = LocateRegistry.getRegistry(host, port);
        Game game = (Game) registry.lookup("Game");
        game.play();
    }

    public static void main(String[] args) throws RemoteException, NotBoundException {
        RMIClient client = new RMIClient("127.0.0.1", 1099);
    }

}

如果只有一个玩家需要通过网络玩游戏,这个实现很有效。我现在遇到的问题是我想登录,以便两个不同的玩家可以通过网络互相对战。主要问题是,我真的不知道在哪里可以使用可能的用户及所有游戏,以及如何查看他们的登录信息。

我想在服务器中保留一个Map<User, Game>并注册正确的游戏,如果用户已登录,但我不知道如何登录,或者如何确保客户端到达正确的位置游戏。

感谢任何帮助

2 个答案:

答案 0 :(得分:2)

当我使用RMI开发2-player minesweeper game时,我想知道完全相同的问题。首先,您必须想知道如何创建游戏?

  1. 您想在前两个可用的玩家之间创建一个游戏(&#34;尽快玩#34;模式)?例如:

    - player1 connects
    - player2 connects
    - the server automatically starts a game between player1 and player2
    
  2. 你想让球员选择他们的对手(沙龙)吗?例如:

    - player1 connects
    - player2 connects
    - player3 connects
    - player1 decides to start a game with player3
    
  3. 如果您决定使用第二种模式,这是一种方法。

    在服务器上,保留当前连接的播放器的列表。每次客户端连接到服务器并成功登录时,将其添加到该列表中:

    /** The connected players */
    private List<Player> connectedPlayers;
    

    同时准备一张地图,其中包含每个玩家关联的游戏实例(顺便说一下,你是在正确的轨道上!)。

    /** The games currently being played */
    private Map<Player, Game> gameList;
    

    当在两个玩家之间创建游戏时(player1想要玩玩家2),将它们添加到游戏列表中。

    Game game = new Game(player1, player2);
    this.gameList.put(player1, game);
    this.gameList.put(player2, game);
    

    如果您需要知道用户是否可用且尚未加入游戏:

    public boolean isUserAvailable(String potentialOpponent) throws RemoteException {
        for (Entry<Player, Game> entry : this.gameList.entrySet()) {
            if (entry.getKey().getUsername().equals(potentialOpponent)) {
                return false;
            }
        }
        return true;
    }
    

    游戏结束后,从地图中删除2名玩家。

    this.gameList.remove(game.getPlayerHost());
    this.gameList.remove(game.getPlayerClient());
    

    我无法在此处复制/粘贴更多代码,但如果您需要灵感,可以在我的游戏中找到source code。这些文件很有趣:

答案 1 :(得分:1)

首先,你在极低的水平上解决这个问题。除非你有充分的理由,否则你应该考虑使用更高级别的抽象,例如......

  1. Spring Framework,还可以选择Spring Security Remoting RMI
  2. Enterprise JavaBeans
  3. Apache Camel
  4. 这些技术将允许您继续使用RMI作为传输,但也可以使用Session Facade轻松构建组件

    单独完成这一切非常繁琐。

    稍微澄清一下我的答案。您应该使用会话外观模式存储您的游戏对象。

    这是你的核心问题......

      

    我不知道如何登录,或者如何确保客户端能够进入正确的游戏。

    这是一个看似复杂的问题。

    1. &#34;如何登录&#34;是帐户服务的实现(包含令牌/ cookie)
    2. &#34;如何确保客户获得正确的游戏&#34;是一个会话范围的实现,它可以保留您的游戏对象并将其返回给呈现正确令牌/凭证的用户。