use of games.strategy.engine.message.ConnectionLostException in project triplea by triplea-game.
the class RemoteMessengerTest method testMethodReturnsOnWait.
@Test
public void testMethodReturnsOnWait() throws Exception {
// when the client shutdown, remotes created
// on the client should not be visible on server
final RemoteName test = new RemoteName(IFoo.class, "test");
ServerMessenger server = null;
ClientMessenger client = null;
try {
server = new ServerMessenger("server", 0);
server.setAcceptNewConnections(true);
final int serverPort = server.getLocalNode().getSocketAddress().getPort();
final String mac = MacFinder.getHashedMacAddress();
client = new ClientMessenger("localhost", serverPort, "client", mac);
final UnifiedMessenger serverUnifiedMessenger = new UnifiedMessenger(server);
final RemoteMessenger serverRemoteMessenger = new RemoteMessenger(serverUnifiedMessenger);
final RemoteMessenger clientRemoteMessenger = new RemoteMessenger(new UnifiedMessenger(client));
final CountDownLatch latch = new CountDownLatch(1);
final AtomicBoolean started = new AtomicBoolean(false);
final IFoo foo = new IFoo() {
@Override
public void foo() {
started.set(true);
Interruptibles.await(latch);
}
};
clientRemoteMessenger.registerRemote(foo, test);
serverUnifiedMessenger.getHub().waitForNodesToImplement(test.getName());
assertTrue(serverUnifiedMessenger.getHub().hasImplementors(test.getName()));
final AtomicReference<ConnectionLostException> rme = new AtomicReference<>(null);
final Thread t = new Thread(() -> {
try {
final IFoo remoteFoo = (IFoo) serverRemoteMessenger.getRemote(test);
remoteFoo.foo();
} catch (final ConnectionLostException e) {
rme.set(e);
}
});
t.start();
// wait for the thread to start
while (started.get() == false) {
Interruptibles.sleep(1);
}
Interruptibles.sleep(20);
// TODO: we are getting a RemoteNotFoundException because the client is disconnecting before the invoke goes out
// completely
// Perhaps this situation should be changed to a ConnectionLostException or something else?
client.shutDown();
// when the client shutdowns, this should wake up.
// and an error should be thrown
// give the thread a chance to execute
t.join(200);
latch.countDown();
assertNotNull(rme.get());
} finally {
shutdownServerAndClient(server, client);
}
}
use of games.strategy.engine.message.ConnectionLostException in project triplea by triplea-game.
the class ServerGame method addObserver.
public void addObserver(final IObserverWaitingToJoin blockingObserver, final IObserverWaitingToJoin nonBlockingObserver, final INode newNode) {
try {
if (!delegateExecutionManager.blockDelegateExecution(2000)) {
nonBlockingObserver.cannotJoinGame("Could not block delegate execution");
return;
}
} catch (final InterruptedException e) {
Thread.currentThread().interrupt();
nonBlockingObserver.cannotJoinGame(e.getMessage());
return;
}
try {
final CountDownLatch waitOnObserver = new CountDownLatch(1);
final byte[] bytes = IoUtils.writeToMemory(this::saveGame);
new Thread(() -> {
try {
blockingObserver.joinGame(bytes, playerManager.getPlayerMapping());
waitOnObserver.countDown();
} catch (final ConnectionLostException cle) {
System.out.println("Connection lost to observer while joining: " + newNode.getName());
} catch (final Exception e) {
ClientLogger.logQuietly("Failed to join game", e);
}
}, "Waiting on observer to finish joining: " + newNode.getName()).start();
try {
if (!waitOnObserver.await(ClientSetting.SERVER_OBSERVER_JOIN_WAIT_TIME.intValue(), TimeUnit.SECONDS)) {
nonBlockingObserver.cannotJoinGame("Taking too long to join.");
}
} catch (final InterruptedException e) {
Thread.currentThread().interrupt();
nonBlockingObserver.cannotJoinGame(e.getMessage());
}
} catch (final Exception e) {
ClientLogger.logQuietly("Failed to join game", e);
nonBlockingObserver.cannotJoinGame(e.getMessage());
} finally {
delegateExecutionManager.resumeDelegateExecution();
}
}
use of games.strategy.engine.message.ConnectionLostException in project triplea by triplea-game.
the class ServerLauncher method launchInNewThread.
@Override
protected void launchInNewThread(final Component parent) {
try {
// the order of this stuff does matter
serverModel.setServerLauncher(this);
serverReady = new ServerReady(clientCount);
if (inGameLobbyWatcher != null) {
inGameLobbyWatcher.setGameStatus(GameDescription.GameStatus.LAUNCHING, null);
}
serverModel.allowRemoveConnections();
ui = parent;
if (headless) {
HeadlessGameServer.log("Game Status: Launching");
}
remoteMessenger.registerRemote(serverReady, ClientModel.CLIENT_READY_CHANNEL);
gameData.doPreGameStartDataModifications(playerListing);
abortLaunch = testShouldWeAbort();
final byte[] gameDataAsBytes = gameData.toBytes();
final Set<IGamePlayer> localPlayerSet = gameData.getGameLoader().createPlayers(playerListing.getLocalPlayerTypes());
final Messengers messengers = new Messengers(messenger, remoteMessenger, channelMessenger);
serverGame = new ServerGame(gameData, localPlayerSet, remotePlayers, messengers);
serverGame.setInGameLobbyWatcher(inGameLobbyWatcher);
if (headless) {
HeadlessGameServer.setServerGame(serverGame);
}
// tell the clients to start,
// later we will wait for them to all
// signal that they are ready.
((IClientChannel) channelMessenger.getChannelBroadcastor(IClientChannel.CHANNEL_NAME)).doneSelectingPlayers(gameDataAsBytes, serverGame.getPlayerManager().getPlayerMapping());
final boolean useSecureRandomSource = !remotePlayers.isEmpty();
if (useSecureRandomSource) {
// server game.
// try to find an opponent to be the other side of the crypto random source.
final PlayerID remotePlayer = serverGame.getPlayerManager().getRemoteOpponent(messenger.getLocalNode(), gameData);
final CryptoRandomSource randomSource = new CryptoRandomSource(remotePlayer, serverGame);
serverGame.setRandomSource(randomSource);
}
try {
gameData.getGameLoader().startGame(serverGame, localPlayerSet, headless);
} catch (final Exception e) {
ClientLogger.logError("Failed to launch", e);
abortLaunch = true;
if (gameLoadingWindow != null) {
gameLoadingWindow.doneWait();
}
}
if (headless) {
HeadlessGameServer.log("Game Successfully Loaded. " + (abortLaunch ? "Aborting Launch." : "Starting Game."));
}
if (abortLaunch) {
serverReady.countDownAll();
}
if (!serverReady.await(ClientSetting.SERVER_START_GAME_SYNC_WAIT_TIME.intValue(), TimeUnit.SECONDS)) {
System.out.println("Waiting for clients to be ready timed out!");
abortLaunch = true;
}
remoteMessenger.unregisterRemote(ClientModel.CLIENT_READY_CHANNEL);
new Thread(() -> {
try {
isLaunching = false;
abortLaunch = testShouldWeAbort();
if (!abortLaunch) {
if (useSecureRandomSource) {
warmUpCryptoRandomSource();
}
if (gameLoadingWindow != null) {
gameLoadingWindow.doneWait();
}
if (headless) {
HeadlessGameServer.log("Starting Game Delegates.");
}
serverGame.startGame();
} else {
stopGame();
if (!headless) {
SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(ui, "Problem during startup, game aborted."));
} else {
System.out.println("Problem during startup, game aborted.");
}
}
} catch (final MessengerException me) {
// if just connection lost, no need to scare the user with some giant stack trace
if (me instanceof ConnectionLostException) {
System.out.println("Game Player disconnection: " + me.getMessage());
} else {
me.printStackTrace(System.out);
}
// wait for the connection handler to notice, and shut us down
try {
// we are already aborting the launch
if (!abortLaunch) {
if (!errorLatch.await(ClientSetting.SERVER_OBSERVER_JOIN_WAIT_TIME.intValue(), TimeUnit.SECONDS)) {
System.err.println("Waiting on error latch timed out!");
}
}
} catch (final InterruptedException e) {
Thread.currentThread().interrupt();
}
stopGame();
} catch (final Exception e) {
e.printStackTrace(System.err);
if (headless) {
System.out.println(DebugUtils.getThreadDumps());
HeadlessGameServer.sendChat("If this is a repeatable issue or error, please make a copy of this savegame " + "and contact a Mod and/or file a bug report.");
}
stopGame();
}
// having an oddball issue with the zip stream being closed while parsing to load default game. might be
// caused by closing of stream while unloading map resources.
Interruptibles.sleep(200);
// either game ended, or aborted, or a player left or disconnected
if (headless) {
try {
System.out.println("Game ended, going back to waiting.");
// if we do not do this, we can get into an infinite loop of launching a game,
// then crashing out, then launching, etc.
serverModel.setAllPlayersToNullNodes();
final File f1 = new File(ClientSetting.SAVE_GAMES_FOLDER_PATH.value(), SaveGameFileChooser.getAutoSaveFileName());
if (f1.exists()) {
gameSelectorModel.load(f1, null);
} else {
gameSelectorModel.resetGameDataToNull();
}
} catch (final Exception e1) {
ClientLogger.logQuietly("Failed to load game", e1);
gameSelectorModel.resetGameDataToNull();
}
} else {
gameSelectorModel.loadDefaultGameNewThread();
}
if (parent != null) {
SwingUtilities.invokeLater(() -> JOptionPane.getFrameForComponent(parent).setVisible(true));
}
serverModel.setServerLauncher(null);
serverModel.newGame();
if (inGameLobbyWatcher != null) {
inGameLobbyWatcher.setGameStatus(GameDescription.GameStatus.WAITING_FOR_PLAYERS, null);
}
if (headless) {
// tell headless server to wait for new connections:
HeadlessGameServer.waitForUsersHeadlessInstance();
HeadlessGameServer.log("Game Status: Waiting For Players");
}
}, "Triplea, start server game").start();
} finally {
if (gameLoadingWindow != null) {
gameLoadingWindow.doneWait();
}
if (inGameLobbyWatcher != null) {
inGameLobbyWatcher.setGameStatus(GameDescription.GameStatus.IN_PROGRESS, serverGame);
}
if (headless) {
HeadlessGameServer.log("Game Status: In Progress");
}
}
}
use of games.strategy.engine.message.ConnectionLostException in project triplea by triplea-game.
the class UnifiedMessenger method messengerInvalid.
private void messengerInvalid() {
synchronized (pendingLock) {
for (final GUID id : pendingInvocations.keySet()) {
final CountDownLatch latch = pendingInvocations.remove(id);
latch.countDown();
results.put(id, new RemoteMethodCallResults(new ConnectionLostException("Connection Lost")));
}
}
}
Aggregations