Smartfoxserver2x handling response synchronization from different Threads

139 Views Asked by At

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

  1. 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

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

}
1

There are 1 best solutions below

0
On

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.