Search code examples
javajava-ee-7wildfly-8

wildfly have a ever running process run in the background


I'm making a html5/js game that will have online capabilities for my backend I've decided to use a wildfly server. The client will communicate with the server via web sockets.

I intended for my wildfly server to also be in charge of game logic decisions such as moving npc's. My plan was to have a @startup bean that would run a server game loop to handle this logic. The server loop would then talk to the serverEndPoint via HornetQ. My serverEndPoint and server loop look like this:

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
    }
}

GameWorld

@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
    }
}

the issue with this is that the server loop freezes everything as it is a infinite loop(for instance if I try and access the html web page I get a 404). obviously this could be solved if the serverLoop was on its own seperate thread but after doing some research it seems threading in jboss is very difficult as its hard to know what dependencies to inject e.t.c

Can anyone shed some light on how I can solve this issue? any help on the matter would be amazing.


Solution

  • What you have encountered has to do with what Java EE is and what it not is: Java EE is optimized for handling many concurrent, short-lived requests, each of which (usually) handle a single transaction. The containers do that very well, particularly with stateless beans, but also with stateful beans (cluster replication etc). As such, Java EE might be well-suited to process the requests coming from your HTML5/JS clients and feed the requests to the messaging infrastructure. Java EE is not, however, designed for long running, thread-blocking background processes like yours.

    FWIW: Another issue that you have not yet encountered is, even if you could get that one fixed: Next you'll encounter the transaction timeout on your @PostConstruct method.

    I think you are better of with moving the game engine out of the Java EE stack. You already mentioned you plan to use HornetQ - then why not put the game engine in a simple standalone application that receives messages from HornetQ and feeds replies back into HornetQ.

    Another option might be a dedicated Java game server engine, see, e.g., this question and its accepted answer on programmers.stackoverflow.com. (Update: it seems the "RedDwarf Server" project mentioned in that answer was discontinued 3 years ago).

    If you absolutely want to use the Java EE environment, I suggest you use a TimerService instead. Note, however, that this also requires that your game loop calculation is quick and guaranteed to finish until the next timeout is scheduled, otherwise the container will skip the scheduled invocation (with a "still running" message or similar).

    Finally, let me mention that if I were to start a new game server today, I would definitely take a look at Akka, Node.js or similar projects that support "reactive" programming.