Various bug fixes

- Closed socket when discovery server crashes, so it can be restarted
- Flattened water on terrain mesh
- Added checks to ensure server is started before connecting
- Added a check to ensure client has started  before connecting to the server
- Fixed concurrency issue in server-> client thread list

Tags: #story[1281]
This commit is contained in:
Michael Rausch
2017-09-28 01:58:49 +13:00
parent 00ddf117b2
commit 8b7407bf89
7 changed files with 301 additions and 213 deletions
+5 -3
View File
@@ -80,12 +80,14 @@ public class App extends Application {
ViewManager.getInstance().initialiseSplashScreen(primaryStage); ViewManager.getInstance().initialiseSplashScreen(primaryStage);
} }
private static void runDiscoveryServer(){ private static void runDiscoveryServer() throws Exception {
while (true){
try { try {
new DiscoveryServer(); new DiscoveryServer();
} }
catch (Exception e){ catch (Exception ignored){
runDiscoveryServer(); ;
}
} }
} }
@@ -11,11 +11,13 @@ import seng302.discoveryServer.util.ServerRepoStreamParser;
import seng302.discoveryServer.util.ServerTable; import seng302.discoveryServer.util.ServerTable;
import seng302.visualiser.ServerListener; import seng302.visualiser.ServerListener;
import java.io.IOException;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.Timer;
public class DiscoveryServer { public class DiscoveryServer {
public static final String ANSI_GREEN = "\u001B[32m"; public static final String ANSI_GREEN = "\u001B[32m";
@@ -27,6 +29,7 @@ public class DiscoveryServer {
private ServerTable serverTable; private ServerTable serverTable;
public static final Integer PORT_NUMBER = 9969; public static final Integer PORT_NUMBER = 9969;
private ServerSocket serverSocket;
private final Logger logger = LoggerFactory.getLogger(DiscoveryServer.class); private final Logger logger = LoggerFactory.getLogger(DiscoveryServer.class);
@@ -56,8 +59,6 @@ public class DiscoveryServer {
displayHeader(); displayHeader();
serverTable = new ServerTable(); serverTable = new ServerTable();
ServerSocket serverSocket;
try{ try{
serverSocket = new ServerSocket(PORT_NUMBER); serverSocket = new ServerSocket(PORT_NUMBER);
} }
@@ -69,6 +70,7 @@ public class DiscoveryServer {
logger.info("Started successfully - Now accepting connections"); logger.info("Started successfully - Now accepting connections");
try{
while (true){ while (true){
Socket clientSocket = serverSocket.accept(); Socket clientSocket = serverSocket.accept();
@@ -77,6 +79,10 @@ public class DiscoveryServer {
clientSocket.close(); clientSocket.close();
} }
} }
catch (Exception e){
close();
}
}
private void parseRequest(Socket clientSocket) throws Exception { private void parseRequest(Socket clientSocket) throws Exception {
@@ -147,6 +153,18 @@ public class DiscoveryServer {
tries++; tries++;
} }
if (serverToJoin != null && serverToJoin.isMaxPlayersReached()){
return null;
}
return serverToJoin; return serverToJoin;
} }
public void close(){
try {
serverSocket.close();
} catch (IOException ignored) {
;
}
}
} }
@@ -40,6 +40,7 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
private boolean terminated; private boolean terminated;
private Thread thread; private Thread thread;
private boolean hasStarted = false;
private ServerSocket serverSocket = null; private ServerSocket serverSocket = null;
private ArrayList<ServerToClientThread> serverToClientThreads = new ArrayList<>(); private ArrayList<ServerToClientThread> serverToClientThreads = new ArrayList<>();
@@ -98,6 +99,8 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
new HeartbeatThread(this); new HeartbeatThread(this);
new ServerListenThread(serverSocket, this); new ServerListenThread(serverSocket, this);
hasStarted = true;
//You should handle interrupts in some way, so that the thread won't keep on forever if you exit the app. //You should handle interrupts in some way, so that the thread won't keep on forever if you exit the app.
while (!terminated) { while (!terminated) {
if (GameState.getPlayerHasLeftFlag()) { if (GameState.getPlayerHasLeftFlag()) {
@@ -146,9 +149,11 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
} }
} }
try { try {
synchronized (this){
for (ServerToClientThread serverToClientThread : serverToClientThreads) { for (ServerToClientThread serverToClientThread : serverToClientThreads) {
serverToClientThread.terminate(); serverToClientThread.terminate();
} }
}
serverSocket.close(); serverSocket.close();
} catch (IOException e) { } catch (IOException e) {
System.out.println("IO error in server thread handler upon closing socket"); System.out.println("IO error in server thread handler upon closing socket");
@@ -450,4 +455,8 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate {
); );
} }
} }
public boolean hasStarted() {
return hasStarted;
}
} }
@@ -1,5 +1,14 @@
package seng302.visualiser; package seng302.visualiser;
import javafx.application.Platform;
import javafx.util.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import seng302.gameServer.messages.*;
import seng302.model.stream.packets.PacketType;
import seng302.model.stream.packets.StreamPacket;
import seng302.utilities.XMLParser;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@@ -42,6 +51,8 @@ import seng302.visualiser.controllers.ViewManager;
*/ */
public class ClientToServerThread implements Runnable { public class ClientToServerThread implements Runnable {
private boolean isStarted = false;
/** /**
* Functional interface for receiving packets from client socket. * Functional interface for receiving packets from client socket.
*/ */
@@ -117,6 +128,8 @@ public class ClientToServerThread implements Runnable {
* variable is false. * variable is false.
*/ */
public void run() { public void run() {
isStarted = true;
int sync1; int sync1;
int sync2; int sync2;
// TODO: 14/07/17 wmu16 - Work out how to fix this while loop // TODO: 14/07/17 wmu16 - Work out how to fix this while loop
@@ -167,8 +180,10 @@ public class ClientToServerThread implements Runnable {
notifyDisconnectListeners("Connection to server was terminated"); notifyDisconnectListeners("Connection to server was terminated");
closeSocket(); closeSocket();
ViewManager.getInstance().goToStartView(); Platform.runLater(() -> {
ViewManager.getInstance().showErrorSnackBar("Server rejected connection."); ViewManager.getInstance().showErrorSnackBar("Server rejected connection.");
ViewManager.getInstance().goToStartView();
});
} }
public void sendCustomizationRequest(CustomizeRequestType reqType, byte[] payload) { public void sendCustomizationRequest(CustomizeRequestType reqType, byte[] payload) {
@@ -194,12 +209,6 @@ public class ClientToServerThread implements Runnable {
if (connectionErrorListener != null){ if (connectionErrorListener != null){
connectionErrorListener.notifyConnectionError(message); connectionErrorListener.notifyConnectionError(message);
} }
try {
this.socket.close();
} catch (IOException e) {
logger.error("Couldn't close socket");
}
} }
/** /**
@@ -390,9 +399,9 @@ public class ClientToServerThread implements Runnable {
} }
if (currentByte == -1) { if (currentByte == -1) {
notifyDisconnectListeners("Cannot read from server."); notifyDisconnectListeners("Cannot read from server.");
closeSocket();
logger.warn("InputStream reach end of stream", 1); logger.warn("InputStream reach end of stream", 1);
handleConnectionError("Could not connect to server. Server is no longer available."); handleConnectionError("Could not connect to server. Server is no longer available.");
closeSocket();
} }
return currentByte; return currentByte;
} }
@@ -435,4 +444,8 @@ public class ClientToServerThread implements Runnable {
).getBuffer() ).getBuffer()
); );
} }
public boolean hasStarted() {
return isStarted;
}
} }
@@ -119,7 +119,7 @@ public class GameClient {
getServerThread().setConnectionErrorListener((eMessage) -> { getServerThread().setConnectionErrorListener((eMessage) -> {
ViewManager.getInstance().showErrorSnackBar(eMessage); ViewManager.getInstance().showErrorSnackBar(eMessage);
destroyClientToServerThread(); //destroyClientToServerThread();
}); });
this.lobbyController = ViewManager.getInstance().goToLobby(true); this.lobbyController = ViewManager.getInstance().goToLobby(true);
@@ -147,18 +147,45 @@ public class GameClient {
server = new MainServerThread(); server = new MainServerThread();
while (!server.hasStarted()){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try { try {
startClientToServerThread(ipAddress, 4942); startClientToServerThread(ipAddress, 4942);
} catch (IOException e) { } catch (IOException e) {
showConnectionError("Cannot connect to server as host"); showConnectionError("Cannot connect to server as host");
} }
// Wait for C2S thread
while (!socketThread.hasStarted()){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
socketThread.sendXML(race, serverName, numLegs, maxPlayers, tokensEnabled); socketThread.sendXML(race, serverName, numLegs, maxPlayers, tokensEnabled);
while (regattaData == null){
int triesLeft = 15;
while (regattaData == null && triesLeft > 0){
try { try {
Thread.sleep(100); Thread.sleep(100);
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
triesLeft--;
}
if (triesLeft <= 0){
showConnectionError("Could not launch server");
return null;
} }
this.lobbyController = ViewManager.getInstance().goToLobby(false); this.lobbyController = ViewManager.getInstance().goToLobby(false);
@@ -119,6 +119,12 @@ public class ServerCreationController implements Initializable {
.runAsHost("localhost", 4941, serverName.getText(), (int) maxPlayersSlider .runAsHost("localhost", 4941, serverName.getText(), (int) maxPlayersSlider
.getValue(), mapMaker.getCurrentRacePath(), (int) legsSlider.getValue(), pickupsCheckBox.isSelected()); .getValue(), mapMaker.getCurrentRacePath(), (int) legsSlider.getValue(), pickupsCheckBox.isSelected());
if (serverDescription == null){
ViewManager.getInstance().getGameClient().getServerThread().closeSocket();
ViewManager.getInstance().getGameClient().stopGame();
return;
}
ViewManager.getInstance().setProperty("serverName", serverDescription.getName()); ViewManager.getInstance().setProperty("serverName", serverDescription.getName());
ViewManager.getInstance().setProperty("mapName", serverDescription.getMapName()); ViewManager.getInstance().setProperty("mapName", serverDescription.getMapName());
} }
File diff suppressed because one or more lines are too long