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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
package pp.mdga.client;
|
||||
|
||||
import pp.mdga.Resources;
|
||||
import pp.mdga.client.ceremonystate.CeremonyStates;
|
||||
import pp.mdga.client.ceremonystate.PodiumState;
|
||||
import pp.mdga.client.ceremonystate.StatisticsState;
|
||||
import pp.mdga.message.server.ShutdownMessage;
|
||||
import pp.mdga.notification.InfoNotification;
|
||||
import pp.mdga.notification.StartDialogNotification;
|
||||
|
||||
public class CeremonyState extends ClientState {
|
||||
|
||||
@@ -77,6 +81,11 @@ public CeremonyStates getState() {
|
||||
return currentState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void received(ShutdownMessage msg){
|
||||
logic.addNotification(new InfoNotification(Resources.stringLookup("server.shutdown")));
|
||||
}
|
||||
|
||||
/**
|
||||
* this method is used to parse the selectNext from the clientGameLogic
|
||||
*/
|
||||
|
||||
@@ -401,9 +401,7 @@ public void received(ServerStartGameMessage msg) {
|
||||
*/
|
||||
@Override
|
||||
public void received(ShutdownMessage msg) {
|
||||
addNotification(new InfoNotification(Resources.stringLookup("server.shutdown")));
|
||||
addNotification(new StartDialogNotification());
|
||||
setState(dialogsState);
|
||||
state.received(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package pp.mdga.client;
|
||||
|
||||
import pp.mdga.Resources;
|
||||
import pp.mdga.game.BonusCard;
|
||||
import pp.mdga.game.Color;
|
||||
import pp.mdga.game.Piece;
|
||||
import pp.mdga.message.server.*;
|
||||
import pp.mdga.notification.InfoNotification;
|
||||
import pp.mdga.notification.StartDialogNotification;
|
||||
|
||||
import java.lang.System.Logger.Level;
|
||||
|
||||
@@ -161,7 +164,9 @@ public void received(ServerStartGameMessage msg) {
|
||||
|
||||
@Override
|
||||
public void received(ShutdownMessage msg) {
|
||||
LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString());
|
||||
logic.addNotification(new InfoNotification(Resources.stringLookup("server.shutdown")));
|
||||
logic.addNotification(new StartDialogNotification());
|
||||
logic.setState(logic.getDialogs());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -141,11 +141,9 @@ public void received(LobbyPlayerJoinedMessage msg) {
|
||||
System.out.println(msg.getId());
|
||||
logic.setOwnPlayerId(msg.getId());
|
||||
}
|
||||
if (msg.isHost() && msg.getId() == logic.getOwnPlayerId()) {
|
||||
logic.setHost(true);
|
||||
if (msg.getPlayer().getColor() != Color.NONE){
|
||||
logic.addNotification(new TskSelectNotification(msg.getPlayer().getColor(), msg.getPlayer().getName(), msg.getPlayer().getName().equals(logic.getOwnPlayerName())));
|
||||
}
|
||||
|
||||
logic.addNotification(new TskSelectNotification(msg.getPlayer().getColor(), msg.getPlayer().getName(), msg.getPlayer().getName().equals(logic.getOwnPlayerName())));
|
||||
logic.getGame().getPlayers().put(msg.getId(), msg.getPlayer());
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import pp.mdga.game.Color;
|
||||
import pp.mdga.message.server.CeremonyMessage;
|
||||
import pp.mdga.message.server.ShutdownMessage;
|
||||
import pp.mdga.server.ServerGameLogic;
|
||||
|
||||
/**
|
||||
@@ -59,6 +60,7 @@ private CeremonyMessage createCeremonyMessage() {
|
||||
public void enter() {
|
||||
LOGGER.log(System.Logger.Level.DEBUG, "Entered CeremonyState state.");
|
||||
logic.getServerSender().broadcast(createCeremonyMessage());
|
||||
logic.getServerSender().shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -86,9 +86,9 @@ public void received(LeaveGameMessage msg, int from) {
|
||||
this.logic.getServerSender().broadcast(new ShutdownMessage());
|
||||
this.logic.getServerSender().shutdown();
|
||||
}
|
||||
this.logic.getServerSender().disconnectClient(from);
|
||||
this.logic.getGame().removePlayer(from);
|
||||
this.logic.getServerSender().broadcast(new LobbyPlayerLeaveMessage(from));
|
||||
this.logic.getServerSender().disconnectClient(from);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user