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;
|
MainView main = (MainView) mainView;
|
||||||
|
|
||||||
main.getJoinDialog().disconnect();
|
main.getJoinDialog().disconnect();
|
||||||
|
System.out.println("Disconnecting from server..." + clientGameLogic.isHost());
|
||||||
|
if (clientGameLogic.isHost()) {
|
||||||
main.getHostDialog().shutdownServer();
|
main.getHostDialog().shutdownServer();
|
||||||
|
}
|
||||||
|
|
||||||
ceremonyView.afterGameCleanup();
|
ceremonyView.afterGameCleanup();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,27 +98,16 @@ protected void startServer() {
|
|||||||
*/
|
*/
|
||||||
public void shutdownServer() {
|
public void shutdownServer() {
|
||||||
|
|
||||||
try {
|
|
||||||
Thread.sleep(1000);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
System.err.println("Thread was interrupted: " + e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (serverInstance != null) {
|
|
||||||
serverInstance.shutdown();
|
serverInstance.shutdown();
|
||||||
serverInstance = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (serverThread != null && serverThread.isAlive()) {
|
// Wait for the server to shut down
|
||||||
serverThread.interrupt();
|
|
||||||
try {
|
try {
|
||||||
serverThread.join();
|
serverThread.join(); // Wait for the server thread to finish
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
serverThread = null;
|
|
||||||
}
|
System.out.println("Server shutdown successfully.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -15,6 +15,9 @@
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.System.Logger;
|
import java.lang.System.Logger;
|
||||||
import java.lang.System.Logger.Level;
|
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.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
@@ -31,6 +34,7 @@ public class MdgaServer implements MessageListener<HostedConnection>, Connection
|
|||||||
private static int port;
|
private static int port;
|
||||||
private final ServerGameLogic logic;
|
private final ServerGameLogic logic;
|
||||||
private final BlockingQueue<ReceivedMessage> pendingMessages = new LinkedBlockingQueue<>();
|
private final BlockingQueue<ReceivedMessage> pendingMessages = new LinkedBlockingQueue<>();
|
||||||
|
private volatile boolean running = true;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// Configure logging
|
// Configure logging
|
||||||
@@ -59,17 +63,19 @@ public MdgaServer(int port) {
|
|||||||
*/
|
*/
|
||||||
public void run() {
|
public void run() {
|
||||||
startServer();
|
startServer();
|
||||||
while (true)
|
while (running) {
|
||||||
processNextMessage();
|
processNextMessage();
|
||||||
}
|
}
|
||||||
|
shutdownServerResources();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Starts the server and initializes listeners.
|
||||||
*/
|
*/
|
||||||
private void startServer() {
|
private void startServer() {
|
||||||
try {
|
try {
|
||||||
LOGGER.log(Level.INFO, "Starting server..."); //NON-NLS
|
LOGGER.log(Level.INFO, "Starting server...");
|
||||||
|
unlockSerializers();//NON-NLS
|
||||||
myServer = Network.createServer(port);
|
myServer = Network.createServer(port);
|
||||||
initializeSerializables();
|
initializeSerializables();
|
||||||
myServer.start();
|
myServer.start();
|
||||||
@@ -77,20 +83,22 @@ private void startServer() {
|
|||||||
LOGGER.log(Level.INFO, "Server started: {0}", myServer.isRunning()); //NON-NLS
|
LOGGER.log(Level.INFO, "Server started: {0}", myServer.isRunning()); //NON-NLS
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOGGER.log(Level.ERROR, "Couldn't start server: {0}", e.getMessage()); //NON-NLS
|
LOGGER.log(Level.ERROR, "Couldn't start server: {0}", e.getMessage()); //NON-NLS
|
||||||
exit(1);
|
exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processNextMessage() {
|
private void processNextMessage() {
|
||||||
try {
|
try {
|
||||||
pendingMessages.take().process(logic);
|
ReceivedMessage message = pendingMessages.take(); // This is a blocking call
|
||||||
|
message.process(logic);
|
||||||
} catch (InterruptedException ex) {
|
} 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();
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeSerializables() {
|
private void initializeSerializables() {
|
||||||
|
|
||||||
Serializer.registerClass(UUID.class, new UUIDSerializer());
|
Serializer.registerClass(UUID.class, new UUIDSerializer());
|
||||||
Serializer.registerClass(AnimationEndMessage.class);
|
Serializer.registerClass(AnimationEndMessage.class);
|
||||||
Serializer.registerClass(ClientStartGameMessage.class);
|
Serializer.registerClass(ClientStartGameMessage.class);
|
||||||
@@ -262,12 +270,12 @@ public void handleDisconnect(int id) {
|
|||||||
this.logic.received(new DisconnectedMessage(), id);
|
this.logic.received(new DisconnectedMessage(), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void exit(int exitValue) { //NON-NLS
|
/**
|
||||||
LOGGER.log(Level.INFO, "close request"); //NON-NLS
|
* Stops the server thread gracefully.
|
||||||
if (myServer != null)
|
*/
|
||||||
for (HostedConnection client : myServer.getConnections()) //NON-NLS
|
public void exit() {
|
||||||
if (client != null) client.close("Game over"); //NON-NLS
|
LOGGER.log(Level.INFO, "Requesting server shutdown"); //NON-NLS
|
||||||
System.exit(exitValue);
|
running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -309,7 +317,11 @@ public void broadcast(ServerMessage message) {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void disconnectClient(int id) {
|
public void disconnectClient(int id) {
|
||||||
|
if (myServer.getConnection(id) != null) {
|
||||||
this.myServer.getConnection(id).close("");
|
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
|
@Override
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
for (HostedConnection client : this.myServer.getConnections()) {
|
this.exit();
|
||||||
if (client != null) {
|
}
|
||||||
client.close("Host closed the server.");
|
|
||||||
|
/**
|
||||||
|
* 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.myServer.close();
|
/**
|
||||||
this.exit(0);
|
* 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;
|
package pp.mdga.client;
|
||||||
|
|
||||||
|
import pp.mdga.Resources;
|
||||||
import pp.mdga.client.ceremonystate.CeremonyStates;
|
import pp.mdga.client.ceremonystate.CeremonyStates;
|
||||||
import pp.mdga.client.ceremonystate.PodiumState;
|
import pp.mdga.client.ceremonystate.PodiumState;
|
||||||
import pp.mdga.client.ceremonystate.StatisticsState;
|
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 {
|
public class CeremonyState extends ClientState {
|
||||||
|
|
||||||
@@ -77,6 +81,11 @@ public CeremonyStates getState() {
|
|||||||
return currentState;
|
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
|
* this method is used to parse the selectNext from the clientGameLogic
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -401,9 +401,7 @@ public void received(ServerStartGameMessage msg) {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void received(ShutdownMessage msg) {
|
public void received(ShutdownMessage msg) {
|
||||||
addNotification(new InfoNotification(Resources.stringLookup("server.shutdown")));
|
state.received(msg);
|
||||||
addNotification(new StartDialogNotification());
|
|
||||||
setState(dialogsState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
package pp.mdga.client;
|
package pp.mdga.client;
|
||||||
|
|
||||||
|
import pp.mdga.Resources;
|
||||||
import pp.mdga.game.BonusCard;
|
import pp.mdga.game.BonusCard;
|
||||||
import pp.mdga.game.Color;
|
import pp.mdga.game.Color;
|
||||||
import pp.mdga.game.Piece;
|
import pp.mdga.game.Piece;
|
||||||
import pp.mdga.message.server.*;
|
import pp.mdga.message.server.*;
|
||||||
|
import pp.mdga.notification.InfoNotification;
|
||||||
|
import pp.mdga.notification.StartDialogNotification;
|
||||||
|
|
||||||
import java.lang.System.Logger.Level;
|
import java.lang.System.Logger.Level;
|
||||||
|
|
||||||
@@ -161,7 +164,9 @@ public void received(ServerStartGameMessage msg) {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void received(ShutdownMessage msg) {
|
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
|
@Override
|
||||||
|
|||||||
@@ -141,11 +141,9 @@ public void received(LobbyPlayerJoinedMessage msg) {
|
|||||||
System.out.println(msg.getId());
|
System.out.println(msg.getId());
|
||||||
logic.setOwnPlayerId(msg.getId());
|
logic.setOwnPlayerId(msg.getId());
|
||||||
}
|
}
|
||||||
if (msg.isHost() && msg.getId() == logic.getOwnPlayerId()) {
|
if (msg.getPlayer().getColor() != Color.NONE){
|
||||||
logic.setHost(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
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());
|
logic.getGame().getPlayers().put(msg.getId(), msg.getPlayer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import pp.mdga.game.Color;
|
import pp.mdga.game.Color;
|
||||||
import pp.mdga.message.server.CeremonyMessage;
|
import pp.mdga.message.server.CeremonyMessage;
|
||||||
|
import pp.mdga.message.server.ShutdownMessage;
|
||||||
import pp.mdga.server.ServerGameLogic;
|
import pp.mdga.server.ServerGameLogic;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -59,6 +60,7 @@ private CeremonyMessage createCeremonyMessage() {
|
|||||||
public void enter() {
|
public void enter() {
|
||||||
LOGGER.log(System.Logger.Level.DEBUG, "Entered CeremonyState state.");
|
LOGGER.log(System.Logger.Level.DEBUG, "Entered CeremonyState state.");
|
||||||
logic.getServerSender().broadcast(createCeremonyMessage());
|
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().broadcast(new ShutdownMessage());
|
||||||
this.logic.getServerSender().shutdown();
|
this.logic.getServerSender().shutdown();
|
||||||
}
|
}
|
||||||
|
this.logic.getServerSender().disconnectClient(from);
|
||||||
this.logic.getGame().removePlayer(from);
|
this.logic.getGame().removePlayer(from);
|
||||||
this.logic.getServerSender().broadcast(new LobbyPlayerLeaveMessage(from));
|
this.logic.getServerSender().broadcast(new LobbyPlayerLeaveMessage(from));
|
||||||
this.logic.getServerSender().disconnectClient(from);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user