Fixed sending wrong race xml when a player disconnected because xml is getting data from gamestate yacht but the yachts are not updated is player disconnect.

Heartbeat packet was sent out at wrong rate which cause the player disconnect detection to be slow. Heartbeat packet is send out every 200ms now.

#story[1055] #pair[hyi25, zyt10]
This commit is contained in:
Zhi You Tan
2017-07-25 17:17:36 +12:00
parent 1a867be387
commit f544734b4d
4 changed files with 73 additions and 120 deletions
@@ -60,6 +60,10 @@ public class GameState {
yachts.put(sourceId, yacht);
}
public static void removeYacht(Integer yachtId) {
yachts.remove(yachtId);
}
public static Boolean getIsRaceStarted() {
return isRaceStarted;
}
@@ -13,7 +13,7 @@ import java.util.*;
* cannot be sent to a player
*/
public class HeartbeatThread extends Thread{
private final int HEARTBEAT_PERIOD = 5000;
private final int HEARTBEAT_PERIOD = 200;
private ClientConnectionDelegate delegate;
private Integer seqNum;
private Stack<Player> disconnectedPlayers;
@@ -137,11 +137,21 @@ public class MainServerThread extends Observable implements Runnable, PacketBuff
*/
@Override
public void clientDisconnected(Player player) {
serverLog("Player disconnected", 0);
try {
player.getSocket().close();
} catch (Exception e) {
serverLog("Cannot disconnect the socket for the disconnected player.", 0);
}
serverLog("Player " + player.getYacht().getSourceId() + "'s socket disconnected", 0);
GameState.removeYacht(player.getYacht().getSourceId());
GameState.removePlayer(player);
for (ServerToClientThread serverToClientThread : serverToClientThreads) {
if (serverToClientThread.getSocket() == player.getSocket()) {
this.deleteObserver(serverToClientThread);
}
}
setChanged();
notifyObservers();
// sendXml();
}
public void startGame() {
@@ -43,9 +43,9 @@ import seng302.server.messages.XMLMessageSubType;
import seng302.utilities.GeoPoint;
/**
* A class describing a single connection to a Client for the purposes of sending and receiving on its own thread.
* All server threads created and owned by the server thread handler which can trigger client updates on its threads
* Created by wmu16 on 13/07/17.
* A class describing a single connection to a Client for the purposes of sending and receiving on
* its own thread. All server threads created and owned by the server thread handler which can
* trigger client updates on its threads Created by wmu16 on 13/07/17.
*/
public class ServerToClientThread implements Runnable, Observer {
@@ -63,7 +63,7 @@ public class ServerToClientThread implements Runnable, Observer {
private Boolean userIdentified = false;
private Boolean connected = true;
private Boolean updateClient = true;
private Boolean initialisedRace = true;
// private Boolean initialisedRace = true;
private Integer seqNo;
private Integer sourceId;
@@ -99,7 +99,8 @@ public class ServerToClientThread implements Runnable, Observer {
static void serverLog(String message, int logLevel) {
if (logLevel <= LOG_LEVEL) {
System.out.println("[SERVER " + LocalDateTime.now().toLocalTime().toString() + "] " + message);
System.out.println(
"[SERVER " + LocalDateTime.now().toLocalTime().toString() + "] " + message);
}
}
@@ -113,83 +114,13 @@ public class ServerToClientThread implements Runnable, Observer {
int sync2;
// TODO: 14/07/17 wmu16 - Work out how to fix this while loop
// used by ryan to simulate sending boats.xml
// InputStream inputStream = getClass().getResourceAsStream("/server_config/boats1.xml");
// StringWriter writer = new StringWriter();
// try {
// IOUtils.copy(inputStream, writer);
// } catch (IOException e) {
// e.printStackTrace();
// }
// String xml = writer.toString();
// Message message = new XMLMessage(xml, XMLMessageSubType.BOAT, 0);
// sendMessage(message);
// System.out.println("[server] send message 1 " + message);
//
// try {
// Thread.sleep(3000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
//
// inputStream = getClass().getResourceAsStream("/server_config/boats.xml");
// writer = new StringWriter();
// try {
// IOUtils.copy(inputStream, writer);
// } catch (IOException e) {
// e.printStackTrace();
// }
// xml = writer.toString();
// message = new XMLMessage(xml, XMLMessageSubType.BOAT, 0);
// sendMessage(message);
// System.out.println("[server] send message 2 " + message);
//
// try {
// Thread.sleep(3000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
//
// inputStream = getClass().getResourceAsStream("/server_config/boats2.xml");
// writer = new StringWriter();
// try {
// IOUtils.copy(inputStream, writer);
// } catch (IOException e) {
// e.printStackTrace();
// }
// xml = writer.toString();
// message = new XMLMessage(xml, XMLMessageSubType.BOAT, 0);
// sendMessage(message);
// System.out.println("[server] send message 3 " + message);
//
// try {
// Thread.sleep(3000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
//
// inputStream = getClass().getResourceAsStream("/server_config/boats.xml");
// writer = new StringWriter();
// try {
// IOUtils.copy(inputStream, writer);
// } catch (IOException e) {
// e.printStackTrace();
// }
// xml = writer.toString();
// message = new XMLMessage(xml, XMLMessageSubType.BOAT, 0);
// sendMessage(message);
// System.out.println("[server] send message 4 " + message);
// sendMessage(getRaceStatusMessage());
// System.out.println("sent race status");
//-------
while(true) {
while (socket.isConnected()) {
try {
if (initialisedRace) {
sendSetupMessages();
initialisedRace = false;
}
// if (initialisedRace) {
// sendSetupMessages();
// initialisedRace = false;
// }
//Perform a write if it is time to as delegated by the MainServerThread
if (updateClient) {
@@ -257,16 +188,18 @@ public class ServerToClientThread implements Runnable, Observer {
xml.setRegatta(new Regatta("RaceVision Test Game", 57.6679590, 11.8503233));
xml.setRace(race);
XMLMessage xmlMessage = new XMLMessage(xml.getRegattaAsXml(), XMLMessageSubType.REGATTA, xml.getRegattaAsXml().length());
XMLMessage xmlMessage = new XMLMessage(xml.getRegattaAsXml(), XMLMessageSubType.REGATTA,
xml.getRegattaAsXml().length());
sendMessage(xmlMessage);
xmlMessage = new XMLMessage(xml.getBoatsAsXml(), XMLMessageSubType.BOAT, xml.getBoatsAsXml().length());
xmlMessage = new XMLMessage(xml.getBoatsAsXml(), XMLMessageSubType.BOAT,
xml.getBoatsAsXml().length());
sendMessage(xmlMessage);
xmlMessage = new XMLMessage(xml.getRaceAsXml(), XMLMessageSubType.RACE, xml.getRaceAsXml().length());
xmlMessage = new XMLMessage(xml.getRaceAsXml(), XMLMessageSubType.RACE,
xml.getRaceAsXml().length());
sendMessage(xmlMessage);
// System.out.println("Sent xml messages for " + thread.getName());
}
public void updateClient() {
@@ -281,6 +214,7 @@ public class ServerToClientThread implements Runnable, Observer {
* if so, sends a confirmation packet back to that connection
* Creates a player instance with that ID and this thread and adds it to the GameState
* If not, close the socket and end the threads execution
*
* @param id the id to try and assign to the connection
* @return A boolean indicating if it was a successful handshake
*/
@@ -315,7 +249,6 @@ public class ServerToClientThread implements Runnable, Observer {
}
private int readByte() throws Exception {
int currentByte = -1;
try {
@@ -349,7 +282,8 @@ public class ServerToClientThread implements Runnable, Observer {
try {
os.write(message.getBuffer());
} catch (SocketException e) {
serverLog("Player " + sourceId + " " + e.getMessage(), 0);
//serverLog("Player " + sourceId + " side socket disconnected", 0);
return;
} catch (IOException e) {
e.printStackTrace();
}
@@ -396,14 +330,14 @@ public class ServerToClientThread implements Runnable, Observer {
if (GameState.getCurrentStage() == GameStages.PRE_RACE) {
boatStatus = BoatStatus.PRESTART;
}
else if(GameState.getCurrentStage() == GameStages.RACING){
} else if (GameState.getCurrentStage() == GameStages.RACING) {
boatStatus = BoatStatus.RACING;
} else {
boatStatus = BoatStatus.UNDEFINED;
}
BoatSubMessage m = new BoatSubMessage(y.getSourceId(), boatStatus, 0, 0, 0, 1234l, 1234l);
BoatSubMessage m = new BoatSubMessage(y.getSourceId(), boatStatus, 0, 0, 0, 1234l,
1234l);
boatSubMessages.add(m);
}
@@ -414,6 +348,11 @@ public class ServerToClientThread implements Runnable, Observer {
}
sendMessage(new RaceStatusMessage(1, raceStatus, startTime, GameState.getWindDirection(),
GameState.getWindSpeed().longValue(), GameState.getPlayers().size(), RaceType.MATCH_RACE, 1, boatSubMessages));
GameState.getWindSpeed().longValue(), GameState.getPlayers().size(),
RaceType.MATCH_RACE, 1, boatSubMessages));
}
public Socket getSocket() {
return socket;
}
}