出于学习目的,因为我是EJB3的新手,我在服务器端使用EJB3实现了桌面游戏Risk作为客户端 - 服务器应用程序。目的是多个用户一起登录并玩游戏。目前,我正在考虑将JSF用于前端。
有多个实例,某些客户'A'的行动需要通知其他客户'B'。例如。如果A攻击B所拥有的国家,B需要知道它,例如考虑要掷多少骰子,以及他们是否想要打牌。
我有@Stateless
个会话bean PlayBean
,其中包含名为attack()
和defend()
的方法,可通过@WebService
或@Remote
接口公开。如果玩家A调用了attack()
,我需要通知受攻击的玩家B,以便B可以决定用defend()
调用哪些参数。具体而言,这相当于A的托管bean调用PlayBean,然后PlayBean调用B的托管bean。如何将此会话bean执行到托管bean回调? (一旦我可以'访问'托管bean,从那里我可以看看JSF的服务器推送功能,直到用户)
我的直觉是让页面bean提供一个回调对象作为会话bean的参数......但这样做是否与EJB3一起工作?
@Stateless
public class PlayBean implements Play {
@Override
public void attack(OccupiedTerritory from, OccupiedTerritory to, int battalions, Set<Leader> leader) {
int attackDice = battalions;
Die die = new Die(6); // TODO read number of sides from cfg
Iterator<Leader> leaderIt = leader.iterator();
int[] roll = new int[attackDice];
for (int i = 0; i < attackDice; i++) {
int bonus = leaderIt.hasNext() ? leaderIt.next().getAttackBonus() : 0;
roll[i] = die.roll(bonus);
}
Arrays.sort(roll);
Player victim = to.getOccupier(); // ...but how do I nudge this player (NOT the player that invoked this method) to act, i.e. to choose how many defence dice to use? I need to get a reference to "victim"'s JSF managed bean.
}
答案 0 :(得分:0)
我认为很多这取决于你没有提供的信息。
例如,如果客户端是胖客户端(Java或其他),则可以在服务器中使用JMS设置消息传递方法。连接时,客户端只需设置一个侦听事件的消息传递客户端。服务器可以使用消息发起事件。如果在客户端中使用Java,则JMS也可以在客户端中使用。但是,如果需要,使用Messaging可以使用不同的语言构建客户端和服务器组件。
如果客户端是瘦的Web应用程序,那么您真正关注Web框架提供的内容(而不是EJB ......尽管JMS仍然可以在服务器中用于触发事件)。像ICEfaces和Primefaces这样的JSF框架支持服务器推送,它允许服务器将更新推送到客户端。我认为ZK也支持这一点,所以它不仅限于JSF。
无论哪种方式,我认为这个问题的答案并不仅仅由EJB描述。希望这会有所帮助。
答案 1 :(得分:0)
您可能应该重新考虑您对完全成熟的EAR以及不同组件的角色的看法。如果您正在使用EJB,则应将应用程序视为事务系统。如果你愿意,很多问题都可以转化为交易问题。
在您的情况下,您应该将JSF托管bean视为控制器扩展或页面的辅助bean。除了向EJB显示信息或隧道操作之外,其中没有逻辑或状态。这表示不需要从EJB中调用它们。
那你的数据模型在哪里? (即谁攻击谁。)对于这个例子,让Singleton EJB保存这些数据可能就足够了。然后,您可以使用PlayBean修改Singleton Data Model Bean的数据。
现在是时候找到最终问题的解决方案了。如何通知玩家数据的变化。 (这就是“你受到攻击”的事情)。如果你使用任何html前端(如JSF),问题总是一样的。没有真正推动网页这样的事情。我看到两个选择:
轮询(如元刷新)或用户手动刷新
使用像Comet 2这样的东西。
所以你的问题不是关于EJB或JAF托管bean,而是关于HTML前端推送通知; - )
只需2美分..