You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
199 lines
7.0 KiB
199 lines
7.0 KiB
package seng302;
|
|
|
|
|
|
import seng302.Model.Boat;
|
|
import seng302.Networking.BinaryMessageEncoder;
|
|
import seng302.Networking.MessageEncoders.RaceVisionByteEncoder;
|
|
import seng302.Networking.MessageEncoders.XMLMessageEncoder;
|
|
import seng302.Networking.Utils.BoatLocationMessage;
|
|
import seng302.Networking.Utils.MessageType;
|
|
import seng302.Networking.Utils.RaceStatus;
|
|
import seng302.Networking.Utils.XMLMessage;
|
|
|
|
import java.io.*;
|
|
import java.net.*;
|
|
|
|
import java.util.concurrent.ArrayBlockingQueue;
|
|
|
|
/**
|
|
* TCP client to recive information from AC35 data source
|
|
*/
|
|
public class MockOutput implements Runnable
|
|
{
|
|
private long lastHeartbeatTime;
|
|
private RaceVisionByteEncoder messageEncoder = new RaceVisionByteEncoder();
|
|
|
|
//socket port 5003 as 4940 is ac35 live port and 4941 is ac35 test port
|
|
private ServerSocket serverSocket;
|
|
private Socket mockSocket;
|
|
private DataOutputStream outToVisualiser;
|
|
|
|
//a buffer that contains items that are waiting to be sent
|
|
private ArrayBlockingQueue<byte[]> messagesToSendBuffer = new ArrayBlockingQueue<>(99999999);
|
|
|
|
private short messageNumber = 1;
|
|
private short xmlSequenceNumber = 1;
|
|
private int heartbeatSequenceNum = 1;
|
|
private int boatLocationSequenceNumber = 1;
|
|
private int raceStatusSequenceNumber = 1;
|
|
private String raceXml;
|
|
private String regattaXml;
|
|
private String boatsXml;
|
|
|
|
|
|
|
|
public MockOutput() throws IOException {
|
|
lastHeartbeatTime = System.currentTimeMillis();
|
|
serverSocket = new ServerSocket(4945);
|
|
}
|
|
/**
|
|
* 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++;
|
|
BinaryMessageEncoder binaryMessageEncoder = new BinaryMessageEncoder(MessageType.HEARTBEAT, System.currentTimeMillis(), messageNumber, (short)heartbeatMessage.length, heartbeatMessage);
|
|
messageNumber++;
|
|
return binaryMessageEncoder.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 synchronized 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();
|
|
|
|
BinaryMessageEncoder binaryMessageEncoder = new BinaryMessageEncoder(MessageType.XMLMESSAGE, System.currentTimeMillis(), messageNumber, (short)encodedXML.length, encodedXML);
|
|
//iterates the message number
|
|
messageNumber++;
|
|
|
|
addMessageToBufferToSend(binaryMessageEncoder.getFullMessage());
|
|
}
|
|
|
|
/**
|
|
* Used to give the mocOutput information about boat location to be made into a message and sent
|
|
*/
|
|
public synchronized void parseBoatLocation(int sourceID, double lat, double lon){
|
|
BoatLocationMessage boatLocationMessage = new BoatLocationMessage(sourceID, lat, lon, boatLocationSequenceNumber);
|
|
//iterates the sequence number
|
|
boatLocationSequenceNumber++;
|
|
|
|
//encodeds the messages
|
|
byte[] encodedBoatLoc = messageEncoder.boatLocation(boatLocationMessage);
|
|
|
|
//encodeds the full message with header
|
|
BinaryMessageEncoder binaryMessageEncoder = new BinaryMessageEncoder(MessageType.BOATLOCATION, System.currentTimeMillis(), messageNumber, (short)encodedBoatLoc.length,
|
|
encodedBoatLoc);
|
|
|
|
//iterates the message number
|
|
messageNumber++;
|
|
|
|
addMessageToBufferToSend(binaryMessageEncoder.getFullMessage());
|
|
}
|
|
|
|
|
|
public synchronized void parseRaceStatus(RaceStatus raceStatus){
|
|
|
|
//iterates the sequence number
|
|
raceStatusSequenceNumber++;
|
|
|
|
//encodeds the messages
|
|
byte[] encodedRaceStatus = messageEncoder.raceStatus(raceStatus);
|
|
|
|
//encodeds the full message with header
|
|
BinaryMessageEncoder binaryMessageEncoder = new BinaryMessageEncoder(MessageType.RACESTATUS, System.currentTimeMillis(), messageNumber, (short)encodedRaceStatus.length,
|
|
encodedRaceStatus);
|
|
|
|
//iterates the message number
|
|
messageNumber++;
|
|
|
|
addMessageToBufferToSend(binaryMessageEncoder.getFullMessage());
|
|
|
|
}
|
|
|
|
private synchronized void addMessageToBufferToSend(byte[] messagesToSendBuffer) {
|
|
this.messagesToSendBuffer.add(messagesToSendBuffer);
|
|
}
|
|
|
|
public void run() {
|
|
|
|
try {
|
|
while (true){
|
|
mockSocket = serverSocket.accept();
|
|
outToVisualiser = new DataOutputStream(mockSocket.getOutputStream());
|
|
|
|
/*******************************Test********************************/
|
|
|
|
while(boatsXml == null || regattaXml == null || raceXml == null) {
|
|
|
|
}
|
|
|
|
parseXMLString(raceXml, XMLMessage.XMLTypeRace);
|
|
parseXMLString(regattaXml, XMLMessage.XMLTypeRegatta);
|
|
parseXMLString(boatsXml, XMLMessage.XMLTypeBoat);
|
|
|
|
/*******************************Test********************************/
|
|
|
|
while(true) {
|
|
try {
|
|
//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();
|
|
}
|
|
}catch(SocketException e){
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public void setRaceXml(String raceXml) {
|
|
this.raceXml = raceXml;
|
|
}
|
|
|
|
|
|
public void setRegattaXml(String regattaXml) {
|
|
this.regattaXml = regattaXml;
|
|
}
|
|
|
|
|
|
public void setBoatsXml(String boatsXml) {
|
|
this.boatsXml = boatsXml;
|
|
}
|
|
|
|
public static void main(String argv[]) throws Exception
|
|
{
|
|
MockOutput client = new MockOutput();
|
|
client.run();
|
|
}
|
|
|
|
} |