Fix: Server Persistence
This commit is contained in:
@@ -42,6 +42,7 @@ public class RMIServer extends UnicastRemoteObject implements IGameServer {
|
||||
BlockingQueue<NetworkEvent> actionQueue;
|
||||
private LimitedMap<String, Boolean> playerList;
|
||||
|
||||
private boolean serverCrashed;
|
||||
|
||||
public RMIServer(GameController controller, int nPort,
|
||||
BlockingQueue<NetworkEvent> actionQueue,
|
||||
@@ -71,6 +72,28 @@ public class RMIServer extends UnicastRemoteObject implements IGameServer {
|
||||
if (preferredInt < 2 || preferredInt > 5) return false;
|
||||
|
||||
synchronized (controller) {
|
||||
if(serverCrashed)
|
||||
{
|
||||
if(controller.getModel().getPlayers().stream().anyMatch(p -> p.getUserName().equals(username))&& !playerList.containsKey(username)) {
|
||||
clients.put(username, callback);
|
||||
playerList.put(username, true);
|
||||
startWatchdog(username);
|
||||
System.out.println("(After crash)Reconnected player: " + username);
|
||||
return true;
|
||||
}
|
||||
if (playerList.containsKey(username) && !playerList.get(username)) {
|
||||
playerList.put(username, true);
|
||||
clients.put(username, callback);
|
||||
System.out.println("Reconnected player: " + username);
|
||||
startWatchdog(username);
|
||||
callback.onGameInit(model);
|
||||
System.out.println("Model sent: " + username);
|
||||
actionQueue.add(new ReconnectPlayer(username));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (playerList.isEmpty()) {
|
||||
model = new Game(preferredInt);
|
||||
controller.setModel(model);
|
||||
@@ -94,6 +117,7 @@ public class RMIServer extends UnicastRemoteObject implements IGameServer {
|
||||
actionQueue.add(new ReconnectPlayer(username));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -263,7 +287,8 @@ public class RMIServer extends UnicastRemoteObject implements IGameServer {
|
||||
* Starts the RMI server.
|
||||
* @return true if the server starts successfully, false otherwise
|
||||
*/
|
||||
public boolean start() {
|
||||
public boolean start(boolean serverCrashed) {
|
||||
this.serverCrashed = serverCrashed;
|
||||
try {
|
||||
System.setProperty("java.rmi.server.hostname", host);
|
||||
registry = LocateRegistry.createRegistry(nPort);
|
||||
|
||||
@@ -35,6 +35,7 @@ public class TCPServer {
|
||||
LimitedMap<String, Boolean> playerList;
|
||||
List<ClientHandler> clientHandlers;
|
||||
|
||||
boolean serverCrashed;
|
||||
// Mappa temporanea: username → ClientHandler
|
||||
// Serve per associare il socket heartbeat al giusto ClientHandler
|
||||
private final Map<String, ClientHandler> pendingHeartbeat = new ConcurrentHashMap<>();
|
||||
@@ -50,7 +51,8 @@ public class TCPServer {
|
||||
this.clientHandlers = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void start() {
|
||||
public void start(boolean serverCrashed) {
|
||||
this.serverCrashed = serverCrashed;
|
||||
try {
|
||||
socketTCP = new ServerSocket(port);
|
||||
heartbeatSocketTCP = new ServerSocket(heartbeatPort);
|
||||
@@ -90,23 +92,55 @@ public class TCPServer {
|
||||
}
|
||||
|
||||
synchronized (controller) {
|
||||
|
||||
String username = eventAddPlayer.getUsername();
|
||||
if(serverCrashed){
|
||||
if(controller.getModel().getPlayers().stream().anyMatch(p -> p.getUserName().equals(username))&& !playerList.containsKey(username)){
|
||||
playerList.put(username, true);
|
||||
System.out.println("(After crash)Reconnected player: " + username);
|
||||
ClientHandler handler = new ClientHandler(
|
||||
username, clientSocket, clientSend, clientReceive,
|
||||
clientHandlers,playerList, actionQueue
|
||||
);
|
||||
clientSocket.getOutputStream().write(1);
|
||||
pendingHeartbeat.put(username, handler);
|
||||
Thread thread = new Thread(handler);
|
||||
thread.start();
|
||||
clientHandlers.add(handler);
|
||||
connectedPlayers++;
|
||||
}
|
||||
else if(playerList.containsKey(username) && !playerList.get(username)){
|
||||
// riconnessione
|
||||
playerList.put(username, true);
|
||||
System.out.println("Reconnected player: " + username);
|
||||
|
||||
ClientHandler handler = new ClientHandler(
|
||||
username, clientSocket, clientSend, clientReceive,
|
||||
clientHandlers, playerList, actionQueue
|
||||
);
|
||||
clientSocket.getOutputStream().write(1);
|
||||
pendingHeartbeat.put(username, handler);
|
||||
handler.notifyModel(controller.getModel());
|
||||
Thread thread = new Thread(handler);
|
||||
thread.start();
|
||||
clientHandlers.add(handler);
|
||||
connectedPlayers++;
|
||||
actionQueue.add(new ReconnectPlayer(username));
|
||||
}
|
||||
else
|
||||
{
|
||||
clientSocket.getOutputStream().write(-1);
|
||||
clientSocket.close();
|
||||
System.out.println("Player could not be added. Connection terminated.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (playerList.isEmpty()) {
|
||||
if(controller.getModel() == null){
|
||||
Game model = new Game(eventAddPlayer.getProposedNPlayer());
|
||||
controller.setModel(model);
|
||||
playerList.setLimit(eventAddPlayer.getProposedNPlayer());
|
||||
}
|
||||
else
|
||||
{
|
||||
for(Player p:controller.getModel().getPlayers()) {
|
||||
playerList.put(p.getUserName(),false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String username = eventAddPlayer.getUsername();
|
||||
|
||||
if (controller.addPlayer(username)) {
|
||||
// nuovo giocatore
|
||||
playerList.put(username, true);
|
||||
@@ -122,8 +156,6 @@ public class TCPServer {
|
||||
clientHandlers.add(handler);
|
||||
connectedPlayers++;
|
||||
// metti in attesa del socket heartbeat
|
||||
|
||||
|
||||
}
|
||||
else if(playerList.containsKey(username) && !playerList.get(username)){
|
||||
// riconnessione
|
||||
@@ -150,6 +182,8 @@ public class TCPServer {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
catch(IOException | ClassNotFoundException e){
|
||||
|
||||
@@ -4,6 +4,7 @@ package it.polimi.ingsw.gc14;
|
||||
import it.polimi.ingsw.gc14.Controller.GameController;
|
||||
import it.polimi.ingsw.gc14.Model.Game;
|
||||
import it.polimi.ingsw.gc14.Model.GamePackage.GameStages;
|
||||
import it.polimi.ingsw.gc14.Model.Player;
|
||||
import it.polimi.ingsw.gc14.Network.NetworkEvent;
|
||||
import it.polimi.ingsw.gc14.Network.NetworkEvents.DisconnectedPlayer;
|
||||
import it.polimi.ingsw.gc14.Network.RMI.Server.RMIServer;
|
||||
@@ -126,7 +127,7 @@ public class ServerLauncher {
|
||||
BlockingQueue<NetworkEvent> actionQueue = new LinkedBlockingQueue<>();
|
||||
GameController gameController = new GameController();
|
||||
String IP;
|
||||
|
||||
boolean serverCrashed;
|
||||
try {
|
||||
IP=chooseNetworkInterface(new Scanner(System.in));
|
||||
} catch (Exception e) {
|
||||
@@ -136,7 +137,12 @@ public class ServerLauncher {
|
||||
RMIServer serverRMI = new RMIServer(gameController, 1099, actionQueue, playerList,IP);
|
||||
TCPServer serverTCP = new TCPServer(gameController, 8080, 8081,actionQueue, playerList);
|
||||
ServerLauncher launcher = new ServerLauncher(actionQueue, gameController, serverRMI, serverTCP);
|
||||
|
||||
if(gameController.getModel() != null){
|
||||
playerList.setLimit(gameController.getModel().getNPlayers());
|
||||
serverCrashed = true;
|
||||
} else {
|
||||
serverCrashed = false;
|
||||
}
|
||||
playerList.setAction(()->{
|
||||
new Thread(()->{
|
||||
try {
|
||||
@@ -149,8 +155,8 @@ public class ServerLauncher {
|
||||
}).start();
|
||||
});
|
||||
|
||||
serverRMI.start();
|
||||
new Thread(()->{serverTCP.start();}).start();
|
||||
serverRMI.start(serverCrashed);
|
||||
new Thread(()->{serverTCP.start(serverCrashed);}).start();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user