package seng302.Networking; import seng302.Networking.MessageEncoders.RaceVisionByteEncoder; import seng302.Networking.MessageEncoders.XMLMessageEncoder; import seng302.Networking.Utils.BoatLocationMessage; import seng302.Networking.Utils.MessageType; import java.io.*; import java.net.*; import java.util.ArrayList; /** * TCP client to recive information from AC35 data source */ public class MockOutput { private long lastHeartbeatTime; private RaceVisionByteEncoder messageEncoder = new RaceVisionByteEncoder(); //socket port 4942 as 4940 is ac35 live port and 4941 is ac35 test port private Socket mockSocket; private DataOutputStream outToVisualiser; //a buffer that contains items that are waiting to be sent private ArrayList messagesToSendBuffer = new ArrayList<>(); private short messageNumber = 1; private short xmlSequenceNumber = 1; private int heartbeatSequenceNum = 1; public MockOutput() throws IOException{ /*******************************Test********************************/ StringBuilder xmlString; BufferedReader br = new BufferedReader(new InputStreamReader( this.getClass().getResourceAsStream(("/raceXML/Regatta.xml")))); String line; xmlString = new StringBuilder(); while((line=br.readLine())!= null){ xmlString.append(line.trim()); } parseXMLString(xmlString.toString(), 5); /*******************************Test********************************/ /**************sockets*******************/ //start Time lastHeartbeatTime = System.currentTimeMillis(); mockSocket = new Socket("localhost", 4942); outToVisualiser = new DataOutputStream(mockSocket.getOutputStream()); //loop that sends while(true) { //sends a heartbeat every 5 seconds if (timeSinceHeartbeat() >= 5.00){ outToVisualiser.write(heartbeat()); lastHeartbeatTime = System.currentTimeMillis(); } //checks the buffer to see if there is anything to send if (messagesToSendBuffer.size() > 0) { for (byte[] binaryMessage : messagesToSendBuffer) { //sends the message to the visualiser outToVisualiser.write(binaryMessage); } //cleans out buffer messagesToSendBuffer.clear(); } } /**************sockets*******************/ } /** * calculates the time since last heartbeat * @return time since last heartbeat */ private double timeSinceHeartbeat() { long now = System.currentTimeMillis(); return (now - lastHeartbeatTime) / 1000.0; } //returns the heartbeat message private byte[] heartbeat(){ byte[] heartbeatMessage = messageEncoder.heartBeat(heartbeatSequenceNum); heartbeatSequenceNum++; BinaryMesageEncoder binaryMesageEncoder = new BinaryMesageEncoder(MessageType.HEARTBEAT, System.currentTimeMillis(), messageNumber, (short)heartbeatMessage.length, heartbeatMessage); messageNumber++; return binaryMesageEncoder.getFullMessage(); } /** * Used to give the mockOutput an xml string to be made into a message and sent * @param xmlString the xml string to send * @param messageType the kind of xml string, values given in AC35 spec (5 regatta, 6 race, 7 boat) */ public void parseXMLString(String xmlString, int messageType){ XMLMessageEncoder encoder = new XMLMessageEncoder(messageNumber, System.currentTimeMillis(), messageType, xmlSequenceNumber,(short) xmlString.length(), xmlString); //iterates the sequence numbers xmlSequenceNumber++; byte[] encodedXML = encoder.encode(); BinaryMesageEncoder binaryMesageEncoder = new BinaryMesageEncoder(MessageType.XMLMESSAGE, System.currentTimeMillis(), messageNumber, (short)encodedXML.length, encodedXML); //iterates the message number messageNumber++; addMessageToBufferToSend(binaryMesageEncoder.getFullMessage()); } /** * Used to give the mocOutput information about boat location to be made into a message and sent */ public void parseBoatLocation(){ /// TODO: 26/04/17 } private void addMessageToBufferToSend(byte[] messagesToSendBuffer) { this.messagesToSendBuffer.add(messagesToSendBuffer); } public static void main(String argv[]) throws Exception { MockOutput client = new MockOutput(); } }