Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic verticles - how to properly design vert.x architecture for a simple vert.x game?

I am trying to develop a proof of concept for Vert.x - a simple realtime browser game.

Let's imagine a game similar to online poker - you have a lobby with a number of existing games that you can join. You can also create a new game (so the number of games in that lobby is variable). In front of that, you have an asynchronous http server (cluster) which players connect to. Especially once in a particular game, everything is real time, so when a player performs some action, others see it immediately without refresh or regular ajax polling.

I was thinking about how to break this functionality into verticles. My first thought is to create a verticle to handle http connections (and to set up the http server to expose selected events on the eventbus to http clients), another verticle to represent the game lobby and third verticle to represent an actual game. The lobby and game verticles would only know about the event bus, they would not handle http at all.

The only thing that is not clear to me, is the scope of these verticles, especially the game verticle, because there will be more (dynamic number of) games. By default, you deploy fixed number of particular verticle instances (in simple apps, that is often only one). In this scenario, this one verticle would have to listen on the eventbus for games' events, decide which game does this event belong to, deserialize the game's state, change it, serialize it and store it again. Then notify all connected players.

What I would like to do instead, is to have a verticle-per-game-instance scope. By this I mean, when a new game is created in the lobby, the lobby verticle would start a new instance of the game verticle, pass it (somehow) a new game ID (so it could bind to events only for that game ID) and this game verticle would store the state for that particular game in-memory, in its instance variables. When the game finishes, the verticle would instruct connected browsers to return to lobby and destroy itself.

Is my way of imagining this correct? If so, what is the best way of achieving this? Especially the part about dynamically creating and destroying verticle instances, with passing some information (ID, etc...) to a newly created verticle?

A bonus question - how can I restrict that the player can only listen to (and send) events from a game he belongs to? So that he does not influence other games. Basically similar thing you would do with sessions/access management in traditional Java Servlet/EE application.

like image 719
Michal Boska Avatar asked Feb 12 '23 10:02

Michal Boska


1 Answers

As there were no answers for some time, I implemented it the way I originally described in the question. It actually went pretty well, the demonstration code can be found here: https://github.com/michalboska/codingbeer-vertx

There is one Verticle (GameLobbyVerticle) that starts a new instance of GameVerticle for each game. The GameVerticle instance remembers (in member variables) all state relevant to particular game instance.

Each instance also creates a few EventBus endpoints (addresses contain the unique game ID, that way each GameVerticle instance has its own unique eventbus endpoints) and listens to system messages, players' input and broadcasts events to connected players. Every instance has "public queue" (accessible by WebSocket clients via eventbus bridge) and "private queue" (unaccessible via the bridge, meant for system messages that we don't want clients to spoof).

Dynamic deployment and un-deployment is done with the container.deployVerticle and container.undeployVerticle API.

like image 102
Michal Boska Avatar answered Feb 14 '23 01:02

Michal Boska