Reputation: 9466
I'm trying to figure out a good way to organize a javax.websocket
multiplayer card game I'm working on.
I want to split up my code into multiple classes which are each a ServerEndpoint
. My problem is that I need an effective way of sharing session data between them.
I have an index at "/index", which is where I'm currently creating Player
objects for clients. I'm setting these like so:
@ServerEndpoint("/index")
public class IndexEndpoint {
@OnOpen
public void openConnection(Session session) {
session.getUserProperties().put("player", new Player());
}
}
And that works; I can access the Player
objects elsewhere throughout IndexEndpoint
.
But when I try to access the user properties from another endpoint (after having established a connection with IndexEndpoint
in JavaScript, waiting 5 seconds and then opening up an additional connection to LobbyEndpoint
on the same page), I get null
.
@ServerEndpoint("/lobby")
public class LobbyEndpoint {
@OnOpen
public void openConnection(Session session) {
System.out.println(session.getUserProperties().get("player")); // prints null
}
}
Which leads me to imply that session data is unfortunately not shared across endpoints.
Is there any good way for me to share websocket session data across multiple classes?
I guess one solution would be to just have one über endpoint for all users to connect to, and which can handle any message type. Then that endpoint delegates message data to other parts of my application.
However I feel like this design would be very messy and restrictive. I'd like to have endpoints dedicated to specific rooms, using annotations like @ServerEndpoint("/rooms/{room-id}")
and @PathParam("room-id")
. So if I was using a monolithic Endpoint then I couldn't do that; I wouldn't be able to know if a connecting user is a user who access to the room.
Upvotes: 2
Views: 1335
Reputation: 415
what about a singleton EJB containing all player and game data?
@Stateless
@ServerEndpoint("/lobby/{sessionKey}")
public class IndexEndpoint {
@EJB
GameData data;
@OnOpen
public void onOpen(Session session, EndpointConfig config,
@PathParam("sessionKey") int id) {
Player player = data.getPlayer(id);
session.getUserProperties().put("player", player);
}
}
The first message from the IndexEndpoint could provide the client with its id and then the client could provide its id to the LobbyEndpoint in the ws URL (or in a header with a Configurator), that is how I plan to do it.
Upvotes: 2