added better network support and disconnecting doesnt clos the client who hosts the server now

This commit is contained in:
Hanno Fleischer
2024-12-11 19:10:46 +01:00
parent f09766eb42
commit f9772732c4
9 changed files with 83 additions and 47 deletions

View File

@@ -339,7 +339,10 @@ public void afterGameCleanup() {
MainView main = (MainView) mainView;
main.getJoinDialog().disconnect();
main.getHostDialog().shutdownServer();
System.out.println("Disconnecting from server..." + clientGameLogic.isHost());
if (clientGameLogic.isHost()) {
main.getHostDialog().shutdownServer();
}
ceremonyView.afterGameCleanup();
}

View File

@@ -98,27 +98,16 @@ protected void startServer() {
*/
public void shutdownServer() {
serverInstance.shutdown();
// Wait for the server to shut down
try {
Thread.sleep(1000);
serverThread.join(); // Wait for the server thread to finish
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.err.println("Thread was interrupted: " + e.getMessage());
}
if (serverInstance != null) {
serverInstance.shutdown();
serverInstance = null;
}
if (serverThread != null && serverThread.isAlive()) {
serverThread.interrupt();
try {
serverThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
serverThread = null;
}
System.out.println("Server shutdown successfully.");
}
/**

View File

@@ -15,6 +15,9 @@
import java.io.IOException;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.BlockingQueue;
@@ -31,6 +34,7 @@ public class MdgaServer implements MessageListener<HostedConnection>, Connection
private static int port;
private final ServerGameLogic logic;
private final BlockingQueue<ReceivedMessage> pendingMessages = new LinkedBlockingQueue<>();
private volatile boolean running = true;
static {
// Configure logging
@@ -59,17 +63,19 @@ public MdgaServer(int port) {
*/
public void run() {
startServer();
while (true)
while (running) {
processNextMessage();
}
shutdownServerResources();
}
/**
*
* Starts the server and initializes listeners.
*/
private void startServer() {
try {
LOGGER.log(Level.INFO, "Starting server..."); //NON-NLS
LOGGER.log(Level.INFO, "Starting server...");
unlockSerializers();//NON-NLS
myServer = Network.createServer(port);
initializeSerializables();
myServer.start();
@@ -77,20 +83,22 @@ private void startServer() {
LOGGER.log(Level.INFO, "Server started: {0}", myServer.isRunning()); //NON-NLS
} catch (IOException e) {
LOGGER.log(Level.ERROR, "Couldn't start server: {0}", e.getMessage()); //NON-NLS
exit(1);
exit();
}
}
private void processNextMessage() {
try {
pendingMessages.take().process(logic);
ReceivedMessage message = pendingMessages.take(); // This is a blocking call
message.process(logic);
} catch (InterruptedException ex) {
LOGGER.log(Level.INFO, "Interrupted while waiting for messages"); //NON-NLS
LOGGER.log(Level.INFO, "Server thread interrupted, shutting down..."); //NON-NLS
Thread.currentThread().interrupt();
}
}
private void initializeSerializables() {
Serializer.registerClass(UUID.class, new UUIDSerializer());
Serializer.registerClass(AnimationEndMessage.class);
Serializer.registerClass(ClientStartGameMessage.class);
@@ -262,12 +270,12 @@ public void handleDisconnect(int id) {
this.logic.received(new DisconnectedMessage(), id);
}
public void exit(int exitValue) { //NON-NLS
LOGGER.log(Level.INFO, "close request"); //NON-NLS
if (myServer != null)
for (HostedConnection client : myServer.getConnections()) //NON-NLS
if (client != null) client.close("Game over"); //NON-NLS
System.exit(exitValue);
/**
* Stops the server thread gracefully.
*/
public void exit() {
LOGGER.log(Level.INFO, "Requesting server shutdown"); //NON-NLS
running = false;
}
/**
@@ -309,7 +317,11 @@ public void broadcast(ServerMessage message) {
*/
@Override
public void disconnectClient(int id) {
this.myServer.getConnection(id).close("");
if (myServer.getConnection(id) != null) {
this.myServer.getConnection(id).close("");
} else {
LOGGER.log(Level.ERROR, "no connection with id={0}", id); //NON-NLS
}
}
/**
@@ -319,13 +331,33 @@ public void disconnectClient(int id) {
*/
@Override
public void shutdown() {
for (HostedConnection client : this.myServer.getConnections()) {
if (client != null) {
client.close("Host closed the server.");
}
}
this.exit();
}
this.myServer.close();
this.exit(0);
/**
* Gracefully shutdown server resources like connections and sockets.
*/
private void shutdownServerResources() {
LOGGER.log(Level.INFO, "Shutting down server resources"); //NON-NLS
if (myServer != null && myServer.isRunning()) {
for (HostedConnection client : myServer.getConnections()) {
if (client != null) client.close("Server shutting down.");
}
myServer.close();
}
}
/**
* This method will be used to unlock the Serializer registry.
*/
private static void unlockSerializers() {
try {
Field lockField = Serializer.class.getDeclaredField("locked");
lockField.setAccessible(true);
lockField.setBoolean(null, false); // Unlock the Serializer registry
} catch (NoSuchFieldException | IllegalAccessException e) {
System.err.println("Failed to unlock the Serializer registry: " + e.getMessage());
e.printStackTrace();
}
}
}