我制作的html5 / js游戏将为我的后端提供在线功能我决定使用wildfly服务器。客户端将通过Web套接字与服务器通信。
我打算让我的wildfly服务器也负责游戏逻辑决策,比如移动npc' s。我的计划是让一个@startup bean运行一个服务器游戏循环来处理这个逻辑。然后,服务器循环将通过HornetQ与serverEndPoint通信。我的serverEndPoint和服务器循环如下所示:
ServerEndPoint
@ServerEndpoint(value= "/game/{user-id}")
public class GameEndpoint {
@Inject
GameManager gameState;
GameWorld gameWorld;
Player p;
private Logger logger = Logger.getLogger(this.getClass().getName());
@OnOpen
public void onOpen(Session session){
//do stuff
}
@OnMessage
public void onMessage(Session session, String message){
//do stuff
}
@OnClose
public void onClose(CloseReason reason){
//do stuff
}
@OnError
public void error(Throwable t){
//do stuff
}
}
游戏世界
@Startup
@Singleton
public class GameWorld {
@Inject
GameManager gameState;
private Logger logger = Logger.getLogger(this.getClass().getName());
@PostConstruct
public void init(){
gameloop();
}
private void gameloop(){
while(true){
logger.info("This is a test!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@PreDestroy
public void terminate(){
//do stuff
}
}
这个问题是服务器循环冻结了所有内容,因为它是一个无限循环(例如,如果我尝试访问html网页,我得到404)。显然这可以解决,如果serverLoop在它自己的单独线程上,但在做了一些研究后,似乎在jboss中的线程非常困难,因为很难知道注入e.t.c的依赖项
有人能说明我如何解决这个问题吗?对此事的任何帮助都会很棒。
答案 0 :(得分:2)
您遇到的问题与Java EE是什么以及它不是什么有关:Java EE针对处理许多并发的短期请求进行了优化,每个请求(通常)处理单个事务。容器做得非常好,特别是对于无状态bean,还有状态bean(集群复制等)。因此,Java EE可能非常适合处理来自HTML5 / JS客户端的请求,并将请求提供给消息传递基础结构。但是,Java EE并不适用于像您这样的长时间运行的线程阻塞后台进程。
FWIW:你还没有遇到的另一个问题是,即使你可以解决这个问题:接下来你会遇到@PostConstruct方法的事务超时。
我认为将Java游戏引擎移出Java EE堆栈会更好。您已经提到过您计划使用HornetQ - 那么为什么不将游戏引擎放在一个简单的独立应用程序中,该应用程序从HornetQ接收消息并将回复反馈回HornetQ。
另一个选项可能是专用的Java游戏服务器引擎,请参阅例如this question及其在programmers.stackoverflow.com上接受的答案。 (更新:该答案中提到的“RedDwarf Server”项目似乎在3年前停止了。)
如果您绝对想要使用Java EE环境,我建议您改用TimerService。但请注意,这还要求您的游戏循环计算快速并保证完成,直到计划下一个超时,否则容器将跳过计划的调用(带有“仍在运行”的消息或类似信息)。
最后,让我提一下,如果我今天要开始一个新的游戏服务器,我肯定会看看Akka,Node.js或支持“被动”编程的类似项目。