added better network support and disconnecting doesnt clos the client who hosts the server now
This commit is contained in:
		@@ -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();
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -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();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user