我正在尝试使用Spring MVC制作此2播放器Web游戏应用程序。我有会话剥落的豆子 Player 和应用程序的豆 GameList, ,创建和存储 Game 实例并将其传递给 Players. 。在玩家创建游戏并从中获得ID GameList 和其他玩家将ID发送到 GameList 并得到 Game 实例。这 Game 实例将其播放器作为属性。问题是每个玩家只看到自己而不是另一个。

每个玩家看到的示例:

  1. 第一个玩家(爱丽丝)创建了一个游戏: Creator: Alice, Joiner: Empty
  2. 第二名玩家(鲍勃)加入游戏: Creator: Bob, Joiner: Bob
  3. 第一播放器刷新她的浏览器 Creator: Alice, Joiner: Alice

我希望他们看到的是 Creator: Alice, Joiner: Bob. 。实现此目的的简单方法是节省有关玩家的信息,而不是对玩家的引用,但是游戏对象需要在其玩家对象上调用方法,因此这不是解决方案。

我认为这是因为 aop:scoped-proxy 会话播放的播放器bean。如果我理解这一点,游戏对象将引用代理,这是指当前会话的播放器对象。游戏实例可以以某种方式保存/访问其他玩家对象吗?

豆子 dispatcher-servlet.xml:

<bean id="userDao" class="authorization.UserDaoFakeImpl"  />
<bean id="gameList" class="model.GameList" />
<bean name="/init/*" class="controller.InitController" >
     <property name="gameList" ref="gameList" />
     <property name="game" ref="game" />
     <property name="player" ref="player" />
</bean>
<bean id="game" class="model.GameContainer" scope="session">
      <aop:scoped-proxy/>
</bean>
<bean id="player" class="beans.Player" scope="session">
      <aop:scoped-proxy/>
</bean>

方法IN controller.initController

private GameList gameList;
private GameContainer game;
private Player player;
public ModelAndView create(HttpServletRequest request,
        HttpServletResponse response) throws Exception {        
    game.setGame(gameList.create(player));        
    return new ModelAndView("redirect:game");
}
public ModelAndView join(HttpServletRequest request,
        HttpServletResponse response, GameId gameId) throws Exception {
    game.setGame(gameList.join(player, gameId.getId()));       
    return new ModelAndView("redirect:game");
}

称为方法 Model.gamelist

public Game create(Player creator) {        
    Integer code = generateCode();        
    Game game = new Game(creator, code);
    games.put(code, game);
    return game;
}
public Game join(Player joiner, Integer code) {
    Game game = games.get(code);
    if (game!=null) {
        game.setJoiner(joiner);           
    }
    return game;
}
有帮助吗?

解决方案

我相信您对代理人是正确的,就是为什么您只看到自己。对代理的任何引用将仅适用于会话中的对象。

您是否需要在范围内进行游戏和玩家?您试图在会话中使用它们的事实表明它们不是会话范围的数据。您可以从工厂创建它们,然后将其引用存储在会话范围的bean中。

另外,如果您确实希望将播放器进行会话范围,则可以在Session Bean中包装对原型的引用。然后,您可以为您的交叉会话数据使用原型参考,以及任何特定于会话的本地数据的会话bean。

可以通过几种方法来解决此问题,但是本质上,您需要将交叉会话数据从会话范围内的bean移出并进入可以共享的应用程序范围bean。

其他提示

您无法从Application-Scope访问不同的会话范围。

但是,您可以解决相反的方式 - 在应用程序划分的bean中注册每个播放器(通过调用 addPlayer(..))

您不能在HTTP会话中拥有游戏数据,因为这仅属于一个用户。

您需要在创作者和木匠的会话中存储对游戏的参考。

是的,最简单的方法是通过以下注释创建代理:

@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)

从春季3.1开始。在过去,您必须使用AOP:XML配置中的scoped-proxy标签

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top