A separate running Thread that are handling Rooms and Users in queue to pick 2 players after client initiates search request
The following is the scenario which I am really concered about and not quite understand wheather or not I am in the right path
lets say Player A and Player B sent search request to Lobby_1 room. Both User objects are added to ConcurrentLinkedQueue which is already mapped to Room ( Looby_1 ) so this condition "if ( queueSize >= 2 )" satisfies and its about to call onSearchSuccess on lobby object sending Player A and Player B as params. Since this is separate thread running concurrently all the time, Lets say Player A quits/disconnects just before this function call "lobby.onSearchSuccess(player1, player2);" since Player A disconnect is happening before executing onSearchSuccess on Lobby, Player A recieves onSearchSuccess and wait for the game to begin forever. If onSearchSuccess execute first and then disconnect, I could let Player A know that Player B is disconnected
Is adding Room and User objects to Collection objects and handling them inside a separate Thread is recommended? is there any problem in doing so ?
I hope I've made my question clear.
How to solve this problem. I don't think introducing synchronization in not the right approach in multiplayer games
public void run() {
if(!isRunning()) {
setRunning(true);
}
while( isRunning() ) {
for(Map.Entry<Room, ConcurrentLinkedQueue<User>> entry : LOBBY_MAP.entrySet()) {
Room room = entry.getKey();
ConcurrentLinkedQueue<User> queue = entry.getValue();
//check queue size
int queueSize = queue.size();
//minimum queue size must be 2 or greater than 2
if ( queueSize >= 2 ) {
logger.debug("QUEUE SIZE: " + queueSize);
User player1 = queue.poll();
User player2 = queue.poll();
//check if both players are not null
if( player1 != null && player2 != null ) {
Lobby lobby = (Lobby) room.getExtension();
lobby.onSearchSuccess(player1, player2);
}
}
}
}
}
public class UserDisconnectHandler extends BaseServerEventHandler {
public void handleServerEvent(ISFSEvent isfse) throws SFSException {
if(isfse.getType() == SFSEventType.USER_DISCONNECT ) {
User user = (User) isfse.getParameter(SFSEventParam.USER);
List<Room> rooms = (List<Room>) isfse.getParameter(SFSEventParam.JOINED_ROOMS);
if( rooms != null ) {
for(Room room : rooms) {
if( !room.isGame() ) {
SearchWorker.getInstance().removeUser(room, user);
//handle users qualified after search success
}
}
}
}
}
}
Why you are using a tread for that ? I did this thing with requests. I mean , when player A request , a listener in server , add him to room FindMatch , then when player B request , you add him to that room too. but , you must check the room size in each request and find out if size is 2 , then remove them from FindMatch room and join them in game room. this is how i did it for my game , with this way , you can even create game room for more than 2 players.