From e83eaa38e182cbdc312cea1d73f32f3df7d61998 Mon Sep 17 00:00:00 2001 From: William Muir Date: Tue, 18 Jul 2017 12:22:58 +1200 Subject: [PATCH] Upon hosting, and then creating a new instance and connecting to that IP, button transmissions work and print out on server!! :D Took the send method out of the Message class as it didnt make sense to have it there. This meant taking it out of all subclasses too tags: #story[1055] pair[wmu16, zyt10] --- src/main/java/seng302/App.java | 1 - .../seng302/client/ClientToServerThread.java | 143 ++++++++ .../client/ClientTransmitterThread.java | 53 --- .../java/seng302/controllers/Controller.java | 19 +- .../controllers/StartScreenController.java | 13 +- .../seng302/gameServer/GameServerThread.java | 7 +- .../seng302/gameServer/HeartbeatThread.java | 12 +- .../MainServerThread.java | 2 +- .../ServerToClientThread.java | 11 +- .../seng302/models/stream/StreamParser.java | 3 - .../seng302/models/stream/StreamReceiver.java | 12 - .../java/seng302/server/ServerThread.java | 332 ------------------ .../seng302/server/StreamingServerSocket.java | 60 ---- .../server/messages/BoatActionMessage.java | 34 +- .../server/messages/BoatLocationMessage.java | 70 ++-- .../seng302/server/messages/Heartbeat.java | 26 +- .../server/messages/MarkRoundingMessage.java | 19 +- .../java/seng302/server/messages/Message.java | 13 +- .../messages/RaceStartStatusMessage.java | 31 +- .../server/messages/RaceStatusMessage.java | 29 +- .../seng302/server/messages/XMLMessage.java | 28 +- 21 files changed, 248 insertions(+), 670 deletions(-) create mode 100644 src/main/java/seng302/client/ClientToServerThread.java delete mode 100644 src/main/java/seng302/client/ClientTransmitterThread.java delete mode 100644 src/main/java/seng302/server/ServerThread.java delete mode 100644 src/main/java/seng302/server/StreamingServerSocket.java diff --git a/src/main/java/seng302/App.java b/src/main/java/seng302/App.java index 95101663..7f04c630 100644 --- a/src/main/java/seng302/App.java +++ b/src/main/java/seng302/App.java @@ -8,7 +8,6 @@ import javafx.stage.Stage; import seng302.models.PolarTable; import seng302.models.stream.StreamParser; import seng302.models.stream.StreamReceiver; -import seng302.server.ServerThread; public class App extends Application { diff --git a/src/main/java/seng302/client/ClientToServerThread.java b/src/main/java/seng302/client/ClientToServerThread.java new file mode 100644 index 00000000..6a7b995d --- /dev/null +++ b/src/main/java/seng302/client/ClientToServerThread.java @@ -0,0 +1,143 @@ +package seng302.client; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; +import java.util.zip.CRC32; +import java.util.zip.Checksum; + +import seng302.models.stream.StreamParser; +import seng302.models.stream.packets.StreamPacket; +import seng302.server.messages.BoatActionMessage; +import seng302.server.messages.BoatActionType; +import seng302.server.messages.Message; + +/** + * Created by kre39 on 13/07/17. + */ +public class ClientToServerThread extends Thread { + private Socket socket; + private InputStream is; + private OutputStream os; + private final int PORT_NUMBER = 0; + private static final int LOG_LEVEL = 1; + + private Boolean updateClient = true; + private ByteArrayOutputStream crcBuffer; + + public ClientToServerThread(String ipAddress, Integer portNumber){ + try { + socket = new Socket(ipAddress, portNumber); + is = socket.getInputStream(); + os = socket.getOutputStream(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + static void serverLog(String message, int logLevel){ + if(logLevel <= LOG_LEVEL){ + System.out.println("[SERVER] " + message); + } + } + + public void run() { + int sync1; + int sync2; + // TODO: 14/07/17 wmu16 - Work out how to fix this while loop + while(true) { + try { + //Perform a write if it is time to as delegated by the MainServerThread + if (updateClient) { + // TODO: 13/07/17 wmu16 - Write out game state - some function that would write all appropriate messages to this output stream +// try { +// GameState.outputState(os); +// } catch (IOException e) { +// System.out.println("IO error in server thread upon writing to output stream"); +// } + updateClient = false; + } + + crcBuffer = new ByteArrayOutputStream(); + sync1 = readByte(); + sync2 = readByte(); + //checking if it is the start of the packet + if(sync1 == 0x47 && sync2 == 0x83) { + int type = readByte(); + //No. of milliseconds since Jan 1st 1970 + long timeStamp = Message.bytesToLong(getBytes(6)); + skipBytes(4); + long payloadLength = Message.bytesToLong(getBytes(2)); + byte[] payload = getBytes((int) payloadLength); + Checksum checksum = new CRC32(); + checksum.update(crcBuffer.toByteArray(), 0, crcBuffer.size()); + long computedCrc = checksum.getValue(); + long packetCrc = Message.bytesToLong(getBytes(4)); + if (computedCrc == packetCrc) { + StreamParser.parsePacket(new StreamPacket(type, payloadLength, timeStamp, payload)); + // TODO: 17/07/17 wmu16 - Fix this or maybe we dont need to go through the main server at all!?!? +// packetBufferDelegate.addToBuffer(new StreamPacket(type, payloadLength, timeStamp, payload)); + } else { + System.err.println("Packet has been dropped"); + } + } + } catch (Exception e) { + closeSocket(); + return; + } + } + + } + + /** + * Send the post-start race course information + */ + public void sendBoatActionMessage(BoatActionMessage boatActionMessage) { + try { + os.write(boatActionMessage.getBuffer()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + + public void closeSocket() { + try { + socket.close(); + } catch (IOException e) { + System.out.println("IO error in server thread upon trying to close socket"); + } + } + + + private int readByte() throws Exception { + int currentByte = -1; + try { + currentByte = is.read(); + crcBuffer.write(currentByte); + } catch (IOException e) { + e.printStackTrace(); + } + if (currentByte == -1){ + throw new Exception(); + } + return currentByte; + } + + private byte[] getBytes(int n) throws Exception{ + byte[] bytes = new byte[n]; + for (int i = 0; i < n; i++){ + bytes[i] = (byte) readByte(); + } + return bytes; + } + + private void skipBytes(long n) throws Exception{ + for (int i=0; i < n; i++){ + readByte(); + } + } + } diff --git a/src/main/java/seng302/client/ClientTransmitterThread.java b/src/main/java/seng302/client/ClientTransmitterThread.java deleted file mode 100644 index 69face4d..00000000 --- a/src/main/java/seng302/client/ClientTransmitterThread.java +++ /dev/null @@ -1,53 +0,0 @@ -package seng302.client; - -import java.io.IOException; - -import seng302.server.StreamingServerSocket; -import seng302.server.messages.BoatActionMessage; - -/** - * Created by kre39 on 13/07/17. - */ -public class ClientTransmitterThread implements Runnable { - private StreamingServerSocket server; - private final int PORT_NUMBER = 0; - private static final int LOG_LEVEL = 1; - - public ClientTransmitterThread(String threadName){ - Thread runner = new Thread(this, threadName); - runner.setDaemon(true); - runner.start(); - - } - - static void serverLog(String message, int logLevel){ - if(logLevel <= LOG_LEVEL){ - System.out.println("[SERVER] " + message); - } - } - - public void run() { - try{ - // Needs to connect to the server: Currently no server is being connect so the boat action keys are not being sent - server = new StreamingServerSocket(PORT_NUMBER); - } - catch (IOException e){ - serverLog("Failed to bind socket: " + e.getMessage(), 0); - } - - // Wait for client to connect - server.start(); - - } - - /** - * Send the post-start race course information - */ - public void sendBoatActionMessage(BoatActionMessage boatActionMessage) { - try { - server.send(boatActionMessage); - } catch (IOException e) { - e.printStackTrace(); - } - } - } diff --git a/src/main/java/seng302/controllers/Controller.java b/src/main/java/seng302/controllers/Controller.java index edb847d0..24d433c9 100644 --- a/src/main/java/seng302/controllers/Controller.java +++ b/src/main/java/seng302/controllers/Controller.java @@ -9,9 +9,8 @@ import javafx.fxml.Initializable; import javafx.scene.Parent; import javafx.scene.input.KeyEvent; import javafx.scene.layout.AnchorPane; -import javafx.scene.layout.Pane; import seng302.models.stream.StreamParser; -import seng302.client.ClientTransmitterThread; +import seng302.client.ClientToServerThread; import seng302.server.messages.BoatActionMessage; import seng302.server.messages.BoatActionType; @@ -19,7 +18,7 @@ public class Controller implements Initializable { @FXML private AnchorPane contentPane; - private ClientTransmitterThread clientTransmitterThread; + private ClientToServerThread clientToServerThread; private Object setContentPane(String jfxUrl) { try { @@ -52,19 +51,19 @@ public class Controller implements Initializable { switch (e.getCode()){ case SPACE: // align with vmg boatActionMessage = new BoatActionMessage(BoatActionType.VMG); - clientTransmitterThread.sendBoatActionMessage(boatActionMessage); + clientToServerThread.sendBoatActionMessage(boatActionMessage); break; case PAGE_UP: // upwind boatActionMessage = new BoatActionMessage(BoatActionType.UPWIND); - clientTransmitterThread.sendBoatActionMessage(boatActionMessage); + clientToServerThread.sendBoatActionMessage(boatActionMessage); break; case PAGE_DOWN: // downwind boatActionMessage = new BoatActionMessage(BoatActionType.DOWNWIND); - clientTransmitterThread.sendBoatActionMessage(boatActionMessage); + clientToServerThread.sendBoatActionMessage(boatActionMessage); break; case ENTER: // tack/gybe boatActionMessage = new BoatActionMessage(BoatActionType.TACK_GYBE); - clientTransmitterThread.sendBoatActionMessage(boatActionMessage); + clientToServerThread.sendBoatActionMessage(boatActionMessage); break; //TODO Allow a zoom in and zoom out methods case Z: // zoom in @@ -81,12 +80,12 @@ public class Controller implements Initializable { //TODO 12/07/17 Determine the sail state and send the appropriate packet (eg. if sails are in, send a sail out packet) case SHIFT: // sails in/sails out BoatActionMessage boatActionMessage = new BoatActionMessage(BoatActionType.SAILS_IN); - clientTransmitterThread.sendBoatActionMessage(boatActionMessage); + clientToServerThread.sendBoatActionMessage(boatActionMessage); break; } } - public void setClientTransmitterThread(ClientTransmitterThread ctt) { - clientTransmitterThread = ctt; + public void setClientToServerThread(ClientToServerThread ctt) { + clientToServerThread = ctt; } } diff --git a/src/main/java/seng302/controllers/StartScreenController.java b/src/main/java/seng302/controllers/StartScreenController.java index 1b219e66..738377a4 100644 --- a/src/main/java/seng302/controllers/StartScreenController.java +++ b/src/main/java/seng302/controllers/StartScreenController.java @@ -6,8 +6,7 @@ import javafx.scene.control.TextField; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.GridPane; import javafx.scene.layout.Pane; -import seng302.client.ClientTransmitterThread; -import seng302.gameServer.GameServerThread; +import seng302.client.ClientToServerThread; import seng302.gameServer.GameState; import seng302.gameServerWithThreading.MainServerThread; import seng302.models.stream.StreamReceiver; @@ -81,17 +80,13 @@ public class StartScreenController { public void connectButtonPressed() { // TODO: 10/07/17 wmu16 - Finish function String ipAddress = ipTextField.getText().trim().toLowerCase(); - //startClientTransmitterThread(); - StreamReceiver sr = new StreamReceiver(ipAddress, 4950, "HostStream"); - sr.start(); + ClientToServerThread clientToServerThread = new ClientToServerThread(ipAddress, 4950); + controller.setClientToServerThread(clientToServerThread); + clientToServerThread.start(); } public void setController(Controller controller) { this.controller = controller; } - - public void startClientTransmitterThread() { - this.controller.setClientTransmitterThread(new ClientTransmitterThread("RaceVision Test Client Transmitter")); - } } diff --git a/src/main/java/seng302/gameServer/GameServerThread.java b/src/main/java/seng302/gameServer/GameServerThread.java index 91d17cc2..9f127773 100644 --- a/src/main/java/seng302/gameServer/GameServerThread.java +++ b/src/main/java/seng302/gameServer/GameServerThread.java @@ -306,14 +306,11 @@ public class GameServerThread implements Runnable, Observer, ClientConnectionDel sendXml(); } - void unicast(Message message, SocketChannel client) throws IOException { - message.send(client); - } void broadcast(Message message) throws IOException{ for(Player player : GameState.getPlayers()) { - //System.out.println("Sending message seqNo[" + seqNum + "] to Player: " + player.toString()); - message.send(player.getSocketChannel()); + //heh + player.getSocketChannel().socket().getOutputStream().write(message.getBuffer()); } seqNum++; } diff --git a/src/main/java/seng302/gameServer/HeartbeatThread.java b/src/main/java/seng302/gameServer/HeartbeatThread.java index e10a85f5..b5ac550e 100644 --- a/src/main/java/seng302/gameServer/HeartbeatThread.java +++ b/src/main/java/seng302/gameServer/HeartbeatThread.java @@ -46,12 +46,12 @@ public class HeartbeatThread extends Thread{ if (!player.getSocketChannel().isConnected()){ playerLostConnection(player); } - - try { - heartbeat.send(player.getSocketChannel()); - } catch (IOException e) { - playerLostConnection(player); - } +// +// try { +// player.getSocketChannel().socket().getOutputStream().write(heartbeat.getBuffer()); +// } catch (IOException e) { +// playerLostConnection(player); +// } } updateDelegate(); diff --git a/src/main/java/seng302/gameServerWithThreading/MainServerThread.java b/src/main/java/seng302/gameServerWithThreading/MainServerThread.java index a53f6e32..226e1dc8 100644 --- a/src/main/java/seng302/gameServerWithThreading/MainServerThread.java +++ b/src/main/java/seng302/gameServerWithThreading/MainServerThread.java @@ -72,7 +72,7 @@ public class MainServerThread extends Thread implements PacketBufferDelegate{ } -// updateClients(); + updateClients(); while (!packetBuffer.isEmpty()){ System.out.println("WHATUPPP"); diff --git a/src/main/java/seng302/gameServerWithThreading/ServerToClientThread.java b/src/main/java/seng302/gameServerWithThreading/ServerToClientThread.java index 757dcab2..957cf043 100644 --- a/src/main/java/seng302/gameServerWithThreading/ServerToClientThread.java +++ b/src/main/java/seng302/gameServerWithThreading/ServerToClientThread.java @@ -35,19 +35,18 @@ public class ServerToClientThread extends Thread { public ServerToClientThread(Socket socket, PacketBufferDelegate packetBufferDelegate) { this.socket = socket; - this.packetBufferDelegate = packetBufferDelegate; - GameState.addPlayer(new Player(socket.getChannel())); - } - - public void run() { try { is = socket.getInputStream(); os = socket.getOutputStream(); } catch (IOException e) { System.out.println("IO error in server thread upon grabbing streams"); } + this.packetBufferDelegate = packetBufferDelegate; + // threeWayHandshake(); + GameState.addPlayer(new Player(socket.getChannel())); + } -// threeWayHandshake(); + public void run() { int sync1; int sync2; diff --git a/src/main/java/seng302/models/stream/StreamParser.java b/src/main/java/seng302/models/stream/StreamParser.java index 3c7b829c..f1ea501a 100644 --- a/src/main/java/seng302/models/stream/StreamParser.java +++ b/src/main/java/seng302/models/stream/StreamParser.java @@ -108,9 +108,6 @@ public class StreamParser{ break; case BOAT_ACTION: extractBoatAction(packet); - default: - //TODO: Haoming added something dumb here. - System.out.println(packet); break; } } catch (NullPointerException e) { diff --git a/src/main/java/seng302/models/stream/StreamReceiver.java b/src/main/java/seng302/models/stream/StreamReceiver.java index a08b7702..8763a1e4 100644 --- a/src/main/java/seng302/models/stream/StreamReceiver.java +++ b/src/main/java/seng302/models/stream/StreamReceiver.java @@ -63,18 +63,6 @@ public class StreamReceiver extends Thread { public void connect(){ - try { - inputStream = host.getInputStream(); - outputStream = host.getOutputStream(); - BoatActionMessage thisMessage = new BoatActionMessage(BoatActionType.TACK_GYBE); - ByteBuffer thisBBMessage = thisMessage.stealBuffer(); - byte[] calumsBuffer = thisBBMessage.array(); - outputStream.write(thisBBMessage.array()); - - } catch (IOException e) { - e.printStackTrace(); - System.exit(1); - } // int sync1; // int sync2; diff --git a/src/main/java/seng302/server/ServerThread.java b/src/main/java/seng302/server/ServerThread.java deleted file mode 100644 index 98038ea2..00000000 --- a/src/main/java/seng302/server/ServerThread.java +++ /dev/null @@ -1,332 +0,0 @@ -package seng302.server; - -import seng302.server.messages.*; -import seng302.server.simulator.Boat; -import seng302.server.simulator.Simulator; - -import java.io.IOException; -import java.io.InputStream; -import java.util.*; - -public class ServerThread implements Runnable, Observer { - private StreamingServerSocket server; - private long startTime; - private boolean raceStarted = false; - private Map boatsFinished = new HashMap<>(); - private List boats; - private Simulator raceSimulator; - private boolean sendingRaceFinishedLocationMessages = true; - - private final int HEARTBEAT_PERIOD = 5000; - private final int RACE_STATUS_PERIOD = 1000/2; - private final int RACE_START_STATUS_PERIOD = 1000; - private final int BOAT_LOCATION_PERIOD = 1000/5; - private final int PORT_NUMBER = 4949; - private final int TIME_TILL_RACE_START = 20*1000; - private static final int LOG_LEVEL = 1; - - public ServerThread(String threadName){ - Thread runner = new Thread(this, threadName); - runner.setDaemon(true); - - raceSimulator = new Simulator(BOAT_LOCATION_PERIOD); - raceSimulator.addObserver(this); - // run race simulator, so it can send boats' static location. - Thread raceSimulatorThread = new Thread(raceSimulator, "Race Simulator"); - - boats = raceSimulator.getBoats(); - - for (Boat b : boats){ - boatsFinished.put(b.getSourceID(), false); - } - - runner.start(); - raceSimulatorThread.start(); - } - - static void serverLog(String message, int logLevel){ - if(logLevel <= LOG_LEVEL){ - System.out.println("[SERVER] " + message); - } - } - - /** - * Creates and returns an XML Message from the file specified - * @param fileName The source XML file - * @param type The XML Message type - * @return The XML Message - */ - private Message getXmlMessage(String fileName, XMLMessageSubType type){ - String fileContents = null; - - try { - InputStream thisStream = this.getClass().getResourceAsStream(fileName); - fileContents = new String(org.apache.commons.io.IOUtils.toByteArray(thisStream)); - } catch (IOException e) { - e.printStackTrace(); - } catch (NullPointerException e){ - return null; - } - - if (fileContents != null){ - return new XMLMessage(fileContents, type, server.getSequenceNumber()); - } - - return null; - } - - /** - * @return Get a race status message for the current race - */ - private Message getRaceStatusMessage(){ - List boatSubMessages = new ArrayList<>(); - BoatStatus boatStatus; - RaceStatus raceStatus; - boolean thereAreBoatsNotFinished = false; - - for (Boat b : boats){ - if (!raceStarted){ - boatStatus = BoatStatus.PRESTART; - thereAreBoatsNotFinished = true; - } - else if(boatsFinished.get(b.getSourceID())){ - boatStatus = BoatStatus.FINISHED; - } - else{ - boatStatus = BoatStatus.PRESTART; - thereAreBoatsNotFinished = true; - } - - BoatSubMessage m = new BoatSubMessage(b.getSourceID(), boatStatus, b.getLastPassedCorner().getSeqID(), 0, 0, b.getEstimatedTimeTillFinish(), b.getEstimatedTimeTillFinish()); - boatSubMessages.add(m); - } - - if (thereAreBoatsNotFinished){ - if (raceStarted){ - raceStatus = RaceStatus.STARTED; - } - else{ - long currentTime = System.currentTimeMillis(); - long timeDifference = startTime - currentTime; - - if (timeDifference > 60*3){ - raceStatus = RaceStatus.PRESTART; - } - else if (timeDifference > 60){ - raceStatus = RaceStatus.WARNING; - } - else{ - raceStatus = RaceStatus.PREPARATORY; - } - } - } - else{ - raceStatus = RaceStatus.TERMINATED; - } - - return new RaceStatusMessage(1, raceStatus, startTime, WindDirection.SOUTH, - 100, boats.size(), RaceType.MATCH_RACE, 1, boatSubMessages); - } - - /** - * Starts an instance of the race simulator - */ - private void startRaceSim(){ - // set race started to true, so the simulator will start moving boats - raceSimulator.setRaceStarted(true); - } - - /** - * Starts sending heartbeat messages to the client - */ - private void startSendingHeartbeats() { - Timer t = new Timer(); - - t.schedule(new TimerTask() { - @Override - public void run() { - Message heartbeat = new Heartbeat(server.getSequenceNumber()); - - try { - server.send(heartbeat); - } catch (IOException e) { - e.printStackTrace(); - } - } - }, 0, HEARTBEAT_PERIOD); - } - - /** - * Start sending race start status messages until race starts - */ - private void startSendingRaceStartStatusMessages(){ - Timer t = new Timer(); - t.schedule(new TimerTask() { - @Override - public void run() { - Message raceStartStatusMessage = new RaceStartStatusMessage(server.getSequenceNumber(), startTime , 1, - RaceStartNotificationType.SET_RACE_START_TIME); - try { - if (startTime < System.currentTimeMillis() && !raceStarted){ - startRaceSim(); - raceStarted = true; - } - else{ - server.send(raceStartStatusMessage); - } - - } catch (IOException e) { - e.printStackTrace(); - } - } - }, 0, RACE_START_STATUS_PERIOD); - } - - /** - * Start sending race start status messages until race starts - */ - private void startSendingRaceStatusMessages(){ - Timer t = new Timer(); - t.schedule(new TimerTask() { - @Override - public void run() { - Message raceStatusMessage = getRaceStatusMessage(); - try { - server.send(raceStatusMessage); - } catch (IOException e) { - e.printStackTrace(); - } - } - }, 0, RACE_STATUS_PERIOD); - } - - /** - * Sends the race, boat, and regatta XML files to the client - */ - private void sendXml(){ - try{ - Message raceData = getXmlMessage("/server_config/race.xml", XMLMessageSubType.RACE); - Message boatData = getXmlMessage("/server_config/boats.xml", XMLMessageSubType.BOAT); - Message regatta = getXmlMessage("/server_config/regatta.xml", XMLMessageSubType.REGATTA); - - if (raceData != null){ - server.send(raceData); - } - if (boatData != null){ - server.send(boatData); - } - if (regatta != null){ - server.send(regatta); - } - } catch (IOException e) { - serverLog("Couldn't send an XML Message: " + e.getMessage(), 0); - } - } - - /** - * Send the post-start race course information - */ - private void sendPostStartCourseXml(){ - Timer t = new Timer(); - t.schedule(new TimerTask() { - @Override - public void run() { - try { - Message raceData = getXmlMessage("/server_config/courseLimits.xml", XMLMessageSubType.RACE); - if (raceData != null) { - server.send(raceData); - } - }catch (IOException e) { - serverLog("Couldn't send an XML Message: " + e.getMessage(), 0); - } - } - },25000); - //Delays the new course xml data for 25 seconds so the boats are able to pass the starting line - } - - public void run() { - try{ - server = new StreamingServerSocket(PORT_NUMBER); - } - catch (IOException e){ - serverLog("Failed to bind socket: " + e.getMessage(), 0); - } - - // Wait for client to connect - server.start(); - - startTime = System.currentTimeMillis() + TIME_TILL_RACE_START; - - startSendingHeartbeats(); - sendXml(); - startSendingRaceStartStatusMessages(); - startSendingRaceStatusMessages(); - sendPostStartCourseXml(); - } - - /** - * Start sending static boat position updates when race has finished - */ - private void startSendingRaceFinishedBoatPositions(){ - Timer t = new Timer(); - t.schedule(new TimerTask() { - @Override - public void run() { - try { - for (Boat b : raceSimulator.getBoats()){ - Message m = new BoatLocationMessage(b.getSourceID(), server.getSequenceNumber(), b.getLat(), - b.getLng(), b.getLastPassedCorner().getBearingToNextCorner(), - ((long) 0)); - - server.send(m); - } - - } catch (IOException e) { - e.printStackTrace(); - } - } - }, 0, BOAT_LOCATION_PERIOD); - } - - /** - * Send a boat location message when they are updated by the simulator - * @param o . - * @param arg . - */ - @Override - @SuppressWarnings("unchecked") - public void update(Observable o, Object arg) { - // Only send if server started - // TODO: I don't understand why i need to check server is null or not ... confused - haoming 2/5/17 - if(server == null || !server.isStarted()){ - return; - } - - int numOfBoatsFinished = 0; - for (Boat boat : (List) arg){ - try { - if (boat.isFinished()) { - numOfBoatsFinished ++; - if (!boatsFinished.get(boat.getSourceID())) { - boatsFinished.put(boat.getSourceID(), true); - } - } - Message m = new BoatLocationMessage(boat.getSourceID(), 1, boat.getLat(), - boat.getLng(), boat.getLastPassedCorner().getBearingToNextCorner(), - ((long) boat.getSpeed())); - server.send(m); - } catch (IOException e) { - serverLog("Couldn't send a boat status message", 3); - return; - } - catch (NullPointerException e){ - e.printStackTrace(); - } - } - - if (numOfBoatsFinished == ((List) arg).size()) { - startSendingRaceFinishedBoatPositions(); - } - - } -} diff --git a/src/main/java/seng302/server/StreamingServerSocket.java b/src/main/java/seng302/server/StreamingServerSocket.java deleted file mode 100644 index 9817f60b..00000000 --- a/src/main/java/seng302/server/StreamingServerSocket.java +++ /dev/null @@ -1,60 +0,0 @@ -package seng302.server; - -import seng302.server.messages.Message; - -import java.io.DataOutputStream; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.nio.channels.Channels; -import java.nio.channels.ServerSocketChannel; -import java.nio.channels.SocketChannel; -import java.nio.channels.WritableByteChannel; -import java.util.ArrayList; -import java.util.List; - -public class StreamingServerSocket { - private ServerSocketChannel socket; - private SocketChannel client; - private short seqNum; - private boolean isServerStarted; - - public StreamingServerSocket(int port) throws IOException{ - socket = ServerSocketChannel.open(); - socket.socket().bind(new InetSocketAddress("localhost", port)); - //socket.setSoTimeout(10000); - seqNum = 0; - isServerStarted = false; - } - - public void start(){ - try { - client = socket.accept(); - } catch (IOException e) { - e.getMessage(); - } - if (client.socket() == null){ - start(); - } - else{ - isServerStarted = true; - } - } - - public void send(Message message) throws IOException{ - if (client == null){ - return; - - } - message.send(client); - seqNum++; - } - - public short getSequenceNumber(){ - return seqNum; - } - - public boolean isStarted(){ - return isServerStarted; - } -} diff --git a/src/main/java/seng302/server/messages/BoatActionMessage.java b/src/main/java/seng302/server/messages/BoatActionMessage.java index 499f209e..9dfc5769 100644 --- a/src/main/java/seng302/server/messages/BoatActionMessage.java +++ b/src/main/java/seng302/server/messages/BoatActionMessage.java @@ -1,8 +1,8 @@ package seng302.server.messages; import java.io.IOException; +import java.io.OutputStream; import java.nio.ByteBuffer; -import java.nio.channels.SocketChannel; /** * Created by kre39 on 12/07/17. @@ -15,6 +15,12 @@ public class BoatActionMessage extends Message{ public BoatActionMessage(BoatActionType actionType) { this.actionType = actionType; setHeader(new Header(MessageType.BOAT_ACTION, 0, (short) 1)); // the second variable is the source id + allocateBuffer(); + writeHeaderToBuffer(); + // Write message fields + putInt((int) BoatActionType.getBoatPacketType(actionType), 1); + writeCRC(); + rewind(); } @@ -23,30 +29,4 @@ public class BoatActionMessage extends Message{ return MESSAGE_SIZE; } - /** - * Send this message as a stream of bytes - * @param outputStream The output stream to send the message - */ - public void send(SocketChannel outputStream) throws IOException { - System.out.println("[CLIENT] Sending boat action type: " + actionType.toString()); - allocateBuffer(); - writeHeaderToBuffer(); - // Write message fields - putInt((int) BoatActionType.getBoatPacketType(actionType), 1); - writeCRC(); - rewind(); - - outputStream.write(getBuffer()); - } - - - public ByteBuffer stealBuffer() { - allocateBuffer(); - writeHeaderToBuffer(); - // Write message fields - putInt((int) BoatActionType.getBoatPacketType(actionType), 1); - writeCRC(); - rewind(); - return getBuffer(); - } } diff --git a/src/main/java/seng302/server/messages/BoatLocationMessage.java b/src/main/java/seng302/server/messages/BoatLocationMessage.java index 97d03465..b4b273a4 100644 --- a/src/main/java/seng302/server/messages/BoatLocationMessage.java +++ b/src/main/java/seng302/server/messages/BoatLocationMessage.java @@ -1,8 +1,7 @@ package seng302.server.messages; import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.channels.SocketChannel; +import java.io.OutputStream; public class BoatLocationMessage extends Message { private final int MESSAGE_SIZE = 56; @@ -65,6 +64,36 @@ public class BoatLocationMessage extends Message { this.rudderAngle = 0; setHeader(new Header(MessageType.BOAT_LOCATION, 1, (short) getSize())); + allocateBuffer(); + writeHeaderToBuffer(); + + long headingToSend = (long)((heading/360.0) * 65535.0); + + putByte((byte) messageVersionNumber); + putInt(time, 6); + putInt((int) sourceId, 4); + putUnsignedInt((int) sequenceNum, 4); + putByte((byte) deviceType.getCode()); + putInt((int) latLonToBinaryPackedLong(latitude), 4); + putInt((int) latLonToBinaryPackedLong(longitude), 4); + putInt((int) altitude, 4); + putInt(headingToSend, 2); + putInt((int) pitch, 2); + putInt((int) roll, 2); + putInt((int) boatSpeed, 2); + putUnsignedInt((int) COG, 2); + putUnsignedInt((int) SOG, 2); + putUnsignedInt((int) apparentWindSpeed, 2); + putInt((int) apparentWindAngle, 2); + putUnsignedInt((int) trueWindSpeed, 2); + putUnsignedInt((int) trueWindDirection, 2); + putInt((int) trueWindAngle, 2); + putUnsignedInt((int) currentDrift, 2); + putUnsignedInt((int) currentSet, 2); + putInt((int) rudderAngle, 2); + + writeCRC(); + rewind(); } /** @@ -125,41 +154,4 @@ public class BoatLocationMessage extends Message { public int getSize() { return MESSAGE_SIZE; } - - - @Override - public void send(SocketChannel outputStream) throws IOException{ - allocateBuffer(); - writeHeaderToBuffer(); - - long headingToSend = (long)((heading/360.0) * 65535.0); - - putByte((byte) messageVersionNumber); - putInt(time, 6); - putInt((int) sourceId, 4); - putUnsignedInt((int) sequenceNum, 4); - putByte((byte) deviceType.getCode()); - putInt((int) latLonToBinaryPackedLong(latitude), 4); - putInt((int) latLonToBinaryPackedLong(longitude), 4); - putInt((int) altitude, 4); - putInt(headingToSend, 2); - putInt((int) pitch, 2); - putInt((int) roll, 2); - putInt((int) boatSpeed, 2); - putUnsignedInt((int) COG, 2); - putUnsignedInt((int) SOG, 2); - putUnsignedInt((int) apparentWindSpeed, 2); - putInt((int) apparentWindAngle, 2); - putUnsignedInt((int) trueWindSpeed, 2); - putUnsignedInt((int) trueWindDirection, 2); - putInt((int) trueWindAngle, 2); - putUnsignedInt((int) currentDrift, 2); - putUnsignedInt((int) currentSet, 2); - putInt((int) rudderAngle, 2); - - writeCRC(); - rewind(); - - outputStream.write(getBuffer()); - } } diff --git a/src/main/java/seng302/server/messages/Heartbeat.java b/src/main/java/seng302/server/messages/Heartbeat.java index 8e619107..c86baac3 100644 --- a/src/main/java/seng302/server/messages/Heartbeat.java +++ b/src/main/java/seng302/server/messages/Heartbeat.java @@ -1,32 +1,16 @@ package seng302.server.messages; -import java.io.DataOutputStream; import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.channels.Channels; -import java.nio.channels.SocketChannel; -import java.nio.channels.WritableByteChannel; -import java.util.zip.CRC32; +import java.io.OutputStream; public class Heartbeat extends Message { private final int MESSAGE_SIZE = 4; - private int seqNo; /** * Heartbeat from the AC35 Streaming data spec * @param seqNo Increment every time a message is sent */ public Heartbeat(int seqNo){ - this.seqNo = seqNo; - } - - @Override - public int getSize() { - return MESSAGE_SIZE; - } - - @Override - public void send(SocketChannel outputStream) throws IOException { setHeader(new Header(MessageType.HEARTBEAT, 0x01, (short) getSize())); allocateBuffer(); @@ -36,7 +20,11 @@ public class Heartbeat extends Message { writeCRC(); rewind(); - - outputStream.write(getBuffer()); } + + @Override + public int getSize() { + return MESSAGE_SIZE; + } + } \ No newline at end of file diff --git a/src/main/java/seng302/server/messages/MarkRoundingMessage.java b/src/main/java/seng302/server/messages/MarkRoundingMessage.java index 750efb22..5a085255 100644 --- a/src/main/java/seng302/server/messages/MarkRoundingMessage.java +++ b/src/main/java/seng302/server/messages/MarkRoundingMessage.java @@ -1,10 +1,7 @@ package seng302.server.messages; -import java.io.DataOutputStream; import java.io.IOException; -import java.nio.channels.Channels; -import java.nio.channels.SocketChannel; -import java.nio.channels.WritableByteChannel; +import java.io.OutputStream; public class MarkRoundingMessage extends Message{ private final long MESSAGE_VERSION_NUMBER = 1; @@ -33,15 +30,6 @@ public class MarkRoundingMessage extends Message{ this.markId = markId; setHeader(new Header(MessageType.MARK_ROUNDING, 1, (short) getSize())); - } - - @Override - public int getSize() { - return MESSAGE_SIZE; - } - - @Override - public void send(SocketChannel outputStream) throws IOException { allocateBuffer(); writeHeaderToBuffer(); @@ -56,7 +44,10 @@ public class MarkRoundingMessage extends Message{ writeCRC(); rewind(); + } - outputStream.write(getBuffer()); + @Override + public int getSize() { + return MESSAGE_SIZE; } } diff --git a/src/main/java/seng302/server/messages/Message.java b/src/main/java/seng302/server/messages/Message.java index 0bcb403e..478ba962 100644 --- a/src/main/java/seng302/server/messages/Message.java +++ b/src/main/java/seng302/server/messages/Message.java @@ -1,9 +1,9 @@ package seng302.server.messages; import java.io.IOException; +import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; -import java.nio.channels.SocketChannel; import java.util.Arrays; import java.util.zip.CRC32; @@ -33,11 +33,6 @@ public abstract class Message { */ public abstract int getSize(); - /** - * Send the message as through the outputStream - */ - public abstract void send(SocketChannel outputStream) throws IOException; - /** * Allocate byte buffer to correct size */ @@ -162,10 +157,10 @@ public abstract class Message { } /** - * @return The current buffer + * @return The current buffer as a byte array */ - public ByteBuffer getBuffer(){ - return buffer; + public byte[] getBuffer(){ + return buffer.array(); } /** diff --git a/src/main/java/seng302/server/messages/RaceStartStatusMessage.java b/src/main/java/seng302/server/messages/RaceStartStatusMessage.java index 9aa886ee..24158d62 100644 --- a/src/main/java/seng302/server/messages/RaceStartStatusMessage.java +++ b/src/main/java/seng302/server/messages/RaceStartStatusMessage.java @@ -1,10 +1,7 @@ package seng302.server.messages; -import java.io.DataOutputStream; import java.io.IOException; -import java.nio.channels.Channels; -import java.nio.channels.SocketChannel; -import java.nio.channels.WritableByteChannel; +import java.io.OutputStream; public class RaceStartStatusMessage extends Message { private final int MESSAGE_SIZE = 20; @@ -32,15 +29,6 @@ public class RaceStartStatusMessage extends Message { this.raceId = raceId; setHeader(new Header(MessageType.RACE_START_STATUS, 1, (short) getSize())); - } - - @Override - public int getSize() { - return MESSAGE_SIZE; - } - - @Override - public void send(SocketChannel outputStream) throws IOException { allocateBuffer(); writeHeaderToBuffer(); @@ -53,16 +41,11 @@ public class RaceStartStatusMessage extends Message { writeCRC(); rewind(); - - if (outputStream == null){ - return; - } - - try{ - outputStream.write(getBuffer()); - } - catch (IOException e){ - return; - } } + + @Override + public int getSize() { + return MESSAGE_SIZE; + } + } diff --git a/src/main/java/seng302/server/messages/RaceStatusMessage.java b/src/main/java/seng302/server/messages/RaceStatusMessage.java index 32ea9abd..2375ba17 100644 --- a/src/main/java/seng302/server/messages/RaceStatusMessage.java +++ b/src/main/java/seng302/server/messages/RaceStatusMessage.java @@ -1,7 +1,7 @@ package seng302.server.messages; import java.io.IOException; -import java.nio.channels.SocketChannel; +import java.io.OutputStream; import java.util.List; import java.util.zip.CRC32; @@ -47,22 +47,6 @@ public class RaceStatusMessage extends Message{ crc = new CRC32(); setHeader(new Header(MESSAGE_TYPE, (int) sourceId, (short) getSize())); - } - - /** - * @return the size of this message in bytes - */ - @Override - public int getSize() { - return MESSAGE_BASE_SIZE + (20 * ((int) numBoatsInRace)); - } - - /** - * Send this message as a stream of bytes - * @param outputStream The output stream to send the message - */ - @Override - public void send(SocketChannel outputStream) throws IOException { allocateBuffer(); writeHeaderToBuffer(); @@ -82,7 +66,14 @@ public class RaceStatusMessage extends Message{ writeCRC(); rewind(); - - outputStream.write(getBuffer()); } + + /** + * @return the size of this message in bytes + */ + @Override + public int getSize() { + return MESSAGE_BASE_SIZE + (20 * ((int) numBoatsInRace)); + } + } diff --git a/src/main/java/seng302/server/messages/XMLMessage.java b/src/main/java/seng302/server/messages/XMLMessage.java index 2cf3a5b5..57d10a00 100644 --- a/src/main/java/seng302/server/messages/XMLMessage.java +++ b/src/main/java/seng302/server/messages/XMLMessage.java @@ -1,12 +1,7 @@ package seng302.server.messages; -import java.io.DataOutputStream; import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.channels.Channels; -import java.nio.channels.SocketChannel; -import java.nio.channels.WritableByteChannel; -import java.util.zip.CRC32; +import java.io.OutputStream; public class XMLMessage extends Message{ private final MessageType MESSAGE_TYPE = MessageType.XML_MESSAGE; @@ -35,20 +30,6 @@ public class XMLMessage extends Message{ sequence = sequenceNum; setHeader(new Header(MESSAGE_TYPE, 0x01, (short) getSize())); - } - - /** - * @return The length of this message - */ - public int getSize(){ - return MESSAGE_SIZE + content.length(); - } - - /** - * Send this message as a stream of bytes - * @param outputStream The output stream to send the message - */ - public void send(SocketChannel outputStream) throws IOException { allocateBuffer(); writeHeaderToBuffer(); @@ -63,7 +44,12 @@ public class XMLMessage extends Message{ writeCRC(); rewind(); + } - outputStream.write(getBuffer()); + /** + * @return The length of this message + */ + public int getSize(){ + return MESSAGE_SIZE + content.length(); } }