HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Waiting for game server connection

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
waitinggameforserverconnection

Problem

public boolean connectedOnGameServer = false;
public final Object conGameServerMonitor = new Object();

public void connectedToGameServer() {
    synchronized (conGameServerMonitor) {
        if (connectedOnGameServer != false)
            throw new RuntimeException("Player connected twice");
        connectedOnGameServer = true;
        conGameServerMonitor.notifyAll();
    }
}

public void waitForGameServerConnection() {
    synchronized (conGameServerMonitor) {
        try {
            long startTime = System.currentTimeMillis();
            long waited = 0;
            while (!connectedOnGameServer && waited  GAMESERVER_CONNECT_TIMEOUT && connectedOnGameServer) {
                throw new RuntimeException("Client didn't connect to game server in time (" + GAMESERVER_CONNECT_TIMEOUT + " ms)");
            }
        } catch (InterruptedException e) {
            throw new RuntimeException("Interrupted while waiting for client to connect to game server", e);
        }
    }
}


What I need is:

  • Thread A calls waitForGameServerConnection



  • Thread B calls connectedToGameServer



  • Thread A continues

Solution

My code examples are excerpts. Don't copy/paste them, they are suggestions you can incorporate into your code.

if (waited > GAMESERVER_CONNECT_TIMEOUT && connectedOnGameServer)
{
   throw new RuntimeException("Client didn't connect to game server in time (" + GAMESERVER_CONNECT_TIMEOUT + " ms)");
}


can be reduced to:

if (!connectedOnServer) {
   throw new RuntimeException("Client didn't connect to game server in time (" + GAMESERVER_CONNECT_TIMEOUT + " ms)");
}


Now, you can handle this without an exception. Connections fail quite regularly, and it's easy to handle that.

public boolean waitForConnection() {
   synchronized (conGameServerMonitor) {
      // loop, guard
      return connectedOnGameServer? true : false;
   }
}


With this you can ask the player if he wants to try again, or wait a bit and try again, etc without having to catch an exception.
But what if B calls connectedToGameServer() after the wait completes?

boolean connectionInProgress;

public void connectedToGame() {
   synchronized (conGameServerMonitor) {
      if (connectionInProgress) {
         connectedOnGameServer = true;
         conGameServerMonitor.notifyAll(); 
      }
   }
}

public boolean waitForConnection() {
   synchronized (conGameServerMonitor) {
      connectionInProgress = true;
      // wait
      connectionInProgress = false;
      return connectedOnGameServer? true : false;
   }
}


You handle the wakeups and interuptions correctly. Kudos for the waited part - I thought "Useless!" for a second, but I forgot that a thread could wake anytime, and it's the thread's responsibility to be sure that it's conditions are fulfilled.

Code Snippets

if (waited > GAMESERVER_CONNECT_TIMEOUT && connectedOnGameServer)
{
   throw new RuntimeException("Client didn't connect to game server in time (" + GAMESERVER_CONNECT_TIMEOUT + " ms)");
}
if (!connectedOnServer) {
   throw new RuntimeException("Client didn't connect to game server in time (" + GAMESERVER_CONNECT_TIMEOUT + " ms)");
}
public boolean waitForConnection() {
   synchronized (conGameServerMonitor) {
      // loop, guard
      return connectedOnGameServer? true : false;
   }
}
boolean connectionInProgress;

public void connectedToGame() {
   synchronized (conGameServerMonitor) {
      if (connectionInProgress) {
         connectedOnGameServer = true;
         conGameServerMonitor.notifyAll(); 
      }
   }
}

public boolean waitForConnection() {
   synchronized (conGameServerMonitor) {
      connectionInProgress = true;
      // wait
      connectionInProgress = false;
      return connectedOnGameServer? true : false;
   }
}

Context

StackExchange Code Review Q#690, answer score: 6

Revisions (0)

No revisions yet.