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]
This commit is contained in:
William Muir
2017-07-18 12:22:58 +12:00
parent 63958a6717
commit e83eaa38e1
21 changed files with 248 additions and 670 deletions
-1
View File
@@ -8,7 +8,6 @@ import javafx.stage.Stage;
import seng302.models.PolarTable; import seng302.models.PolarTable;
import seng302.models.stream.StreamParser; import seng302.models.stream.StreamParser;
import seng302.models.stream.StreamReceiver; import seng302.models.stream.StreamReceiver;
import seng302.server.ServerThread;
public class App extends Application { public class App extends Application {
@@ -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();
}
}
}
@@ -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();
}
}
}
@@ -9,9 +9,8 @@ import javafx.fxml.Initializable;
import javafx.scene.Parent; import javafx.scene.Parent;
import javafx.scene.input.KeyEvent; import javafx.scene.input.KeyEvent;
import javafx.scene.layout.AnchorPane; import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import seng302.models.stream.StreamParser; import seng302.models.stream.StreamParser;
import seng302.client.ClientTransmitterThread; import seng302.client.ClientToServerThread;
import seng302.server.messages.BoatActionMessage; import seng302.server.messages.BoatActionMessage;
import seng302.server.messages.BoatActionType; import seng302.server.messages.BoatActionType;
@@ -19,7 +18,7 @@ public class Controller implements Initializable {
@FXML @FXML
private AnchorPane contentPane; private AnchorPane contentPane;
private ClientTransmitterThread clientTransmitterThread; private ClientToServerThread clientToServerThread;
private Object setContentPane(String jfxUrl) { private Object setContentPane(String jfxUrl) {
try { try {
@@ -52,19 +51,19 @@ public class Controller implements Initializable {
switch (e.getCode()){ switch (e.getCode()){
case SPACE: // align with vmg case SPACE: // align with vmg
boatActionMessage = new BoatActionMessage(BoatActionType.VMG); boatActionMessage = new BoatActionMessage(BoatActionType.VMG);
clientTransmitterThread.sendBoatActionMessage(boatActionMessage); clientToServerThread.sendBoatActionMessage(boatActionMessage);
break; break;
case PAGE_UP: // upwind case PAGE_UP: // upwind
boatActionMessage = new BoatActionMessage(BoatActionType.UPWIND); boatActionMessage = new BoatActionMessage(BoatActionType.UPWIND);
clientTransmitterThread.sendBoatActionMessage(boatActionMessage); clientToServerThread.sendBoatActionMessage(boatActionMessage);
break; break;
case PAGE_DOWN: // downwind case PAGE_DOWN: // downwind
boatActionMessage = new BoatActionMessage(BoatActionType.DOWNWIND); boatActionMessage = new BoatActionMessage(BoatActionType.DOWNWIND);
clientTransmitterThread.sendBoatActionMessage(boatActionMessage); clientToServerThread.sendBoatActionMessage(boatActionMessage);
break; break;
case ENTER: // tack/gybe case ENTER: // tack/gybe
boatActionMessage = new BoatActionMessage(BoatActionType.TACK_GYBE); boatActionMessage = new BoatActionMessage(BoatActionType.TACK_GYBE);
clientTransmitterThread.sendBoatActionMessage(boatActionMessage); clientToServerThread.sendBoatActionMessage(boatActionMessage);
break; break;
//TODO Allow a zoom in and zoom out methods //TODO Allow a zoom in and zoom out methods
case Z: // zoom in 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) //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 case SHIFT: // sails in/sails out
BoatActionMessage boatActionMessage = new BoatActionMessage(BoatActionType.SAILS_IN); BoatActionMessage boatActionMessage = new BoatActionMessage(BoatActionType.SAILS_IN);
clientTransmitterThread.sendBoatActionMessage(boatActionMessage); clientToServerThread.sendBoatActionMessage(boatActionMessage);
break; break;
} }
} }
public void setClientTransmitterThread(ClientTransmitterThread ctt) { public void setClientToServerThread(ClientToServerThread ctt) {
clientTransmitterThread = ctt; clientToServerThread = ctt;
} }
} }
@@ -6,8 +6,7 @@ import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane; import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane; import javafx.scene.layout.Pane;
import seng302.client.ClientTransmitterThread; import seng302.client.ClientToServerThread;
import seng302.gameServer.GameServerThread;
import seng302.gameServer.GameState; import seng302.gameServer.GameState;
import seng302.gameServerWithThreading.MainServerThread; import seng302.gameServerWithThreading.MainServerThread;
import seng302.models.stream.StreamReceiver; import seng302.models.stream.StreamReceiver;
@@ -81,17 +80,13 @@ public class StartScreenController {
public void connectButtonPressed() { public void connectButtonPressed() {
// TODO: 10/07/17 wmu16 - Finish function // TODO: 10/07/17 wmu16 - Finish function
String ipAddress = ipTextField.getText().trim().toLowerCase(); String ipAddress = ipTextField.getText().trim().toLowerCase();
//startClientTransmitterThread(); ClientToServerThread clientToServerThread = new ClientToServerThread(ipAddress, 4950);
StreamReceiver sr = new StreamReceiver(ipAddress, 4950, "HostStream"); controller.setClientToServerThread(clientToServerThread);
sr.start(); clientToServerThread.start();
} }
public void setController(Controller controller) { public void setController(Controller controller) {
this.controller = controller; this.controller = controller;
} }
public void startClientTransmitterThread() {
this.controller.setClientTransmitterThread(new ClientTransmitterThread("RaceVision Test Client Transmitter"));
}
} }
@@ -306,14 +306,11 @@ public class GameServerThread implements Runnable, Observer, ClientConnectionDel
sendXml(); sendXml();
} }
void unicast(Message message, SocketChannel client) throws IOException {
message.send(client);
}
void broadcast(Message message) throws IOException{ void broadcast(Message message) throws IOException{
for(Player player : GameState.getPlayers()) { for(Player player : GameState.getPlayers()) {
//System.out.println("Sending message seqNo[" + seqNum + "] to Player: " + player.toString()); //heh
message.send(player.getSocketChannel()); player.getSocketChannel().socket().getOutputStream().write(message.getBuffer());
} }
seqNum++; seqNum++;
} }
@@ -46,12 +46,12 @@ public class HeartbeatThread extends Thread{
if (!player.getSocketChannel().isConnected()){ if (!player.getSocketChannel().isConnected()){
playerLostConnection(player); playerLostConnection(player);
} }
//
try { // try {
heartbeat.send(player.getSocketChannel()); // player.getSocketChannel().socket().getOutputStream().write(heartbeat.getBuffer());
} catch (IOException e) { // } catch (IOException e) {
playerLostConnection(player); // playerLostConnection(player);
} // }
} }
updateDelegate(); updateDelegate();
@@ -72,7 +72,7 @@ public class MainServerThread extends Thread implements PacketBufferDelegate{
} }
// updateClients(); updateClients();
while (!packetBuffer.isEmpty()){ while (!packetBuffer.isEmpty()){
System.out.println("WHATUPPP"); System.out.println("WHATUPPP");
@@ -35,19 +35,18 @@ public class ServerToClientThread extends Thread {
public ServerToClientThread(Socket socket, PacketBufferDelegate packetBufferDelegate) { public ServerToClientThread(Socket socket, PacketBufferDelegate packetBufferDelegate) {
this.socket = socket; this.socket = socket;
this.packetBufferDelegate = packetBufferDelegate;
GameState.addPlayer(new Player(socket.getChannel()));
}
public void run() {
try { try {
is = socket.getInputStream(); is = socket.getInputStream();
os = socket.getOutputStream(); os = socket.getOutputStream();
} catch (IOException e) { } catch (IOException e) {
System.out.println("IO error in server thread upon grabbing streams"); 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 sync1;
int sync2; int sync2;
@@ -108,9 +108,6 @@ public class StreamParser{
break; break;
case BOAT_ACTION: case BOAT_ACTION:
extractBoatAction(packet); extractBoatAction(packet);
default:
//TODO: Haoming added something dumb here.
System.out.println(packet);
break; break;
} }
} catch (NullPointerException e) { } catch (NullPointerException e) {
@@ -63,18 +63,6 @@ public class StreamReceiver extends Thread {
public void connect(){ 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 sync1;
// int sync2; // int sync2;
@@ -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<Integer,Boolean> boatsFinished = new HashMap<>();
private List<Boat> 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<BoatSubMessage> 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<Boat>) 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<Boat>) arg).size()) {
startSendingRaceFinishedBoatPositions();
}
}
}
@@ -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;
}
}
@@ -1,8 +1,8 @@
package seng302.server.messages; package seng302.server.messages;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
/** /**
* Created by kre39 on 12/07/17. * Created by kre39 on 12/07/17.
@@ -15,6 +15,12 @@ public class BoatActionMessage extends Message{
public BoatActionMessage(BoatActionType actionType) { public BoatActionMessage(BoatActionType actionType) {
this.actionType = actionType; this.actionType = actionType;
setHeader(new Header(MessageType.BOAT_ACTION, 0, (short) 1)); // the second variable is the source id 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; 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();
}
} }
@@ -1,8 +1,7 @@
package seng302.server.messages; package seng302.server.messages;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.io.OutputStream;
import java.nio.channels.SocketChannel;
public class BoatLocationMessage extends Message { public class BoatLocationMessage extends Message {
private final int MESSAGE_SIZE = 56; private final int MESSAGE_SIZE = 56;
@@ -65,6 +64,36 @@ public class BoatLocationMessage extends Message {
this.rudderAngle = 0; this.rudderAngle = 0;
setHeader(new Header(MessageType.BOAT_LOCATION, 1, (short) getSize())); 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() { public int getSize() {
return MESSAGE_SIZE; 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());
}
} }
@@ -1,32 +1,16 @@
package seng302.server.messages; package seng302.server.messages;
import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.io.OutputStream;
import java.nio.channels.Channels;
import java.nio.channels.SocketChannel;
import java.nio.channels.WritableByteChannel;
import java.util.zip.CRC32;
public class Heartbeat extends Message { public class Heartbeat extends Message {
private final int MESSAGE_SIZE = 4; private final int MESSAGE_SIZE = 4;
private int seqNo;
/** /**
* Heartbeat from the AC35 Streaming data spec * Heartbeat from the AC35 Streaming data spec
* @param seqNo Increment every time a message is sent * @param seqNo Increment every time a message is sent
*/ */
public Heartbeat(int seqNo){ 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())); setHeader(new Header(MessageType.HEARTBEAT, 0x01, (short) getSize()));
allocateBuffer(); allocateBuffer();
@@ -36,7 +20,11 @@ public class Heartbeat extends Message {
writeCRC(); writeCRC();
rewind(); rewind();
outputStream.write(getBuffer());
} }
@Override
public int getSize() {
return MESSAGE_SIZE;
}
} }
@@ -1,10 +1,7 @@
package seng302.server.messages; package seng302.server.messages;
import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.channels.Channels; import java.io.OutputStream;
import java.nio.channels.SocketChannel;
import java.nio.channels.WritableByteChannel;
public class MarkRoundingMessage extends Message{ public class MarkRoundingMessage extends Message{
private final long MESSAGE_VERSION_NUMBER = 1; private final long MESSAGE_VERSION_NUMBER = 1;
@@ -33,15 +30,6 @@ public class MarkRoundingMessage extends Message{
this.markId = markId; this.markId = markId;
setHeader(new Header(MessageType.MARK_ROUNDING, 1, (short) getSize())); 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(); allocateBuffer();
writeHeaderToBuffer(); writeHeaderToBuffer();
@@ -56,7 +44,10 @@ public class MarkRoundingMessage extends Message{
writeCRC(); writeCRC();
rewind(); rewind();
}
outputStream.write(getBuffer()); @Override
public int getSize() {
return MESSAGE_SIZE;
} }
} }
@@ -1,9 +1,9 @@
package seng302.server.messages; package seng302.server.messages;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.nio.channels.SocketChannel;
import java.util.Arrays; import java.util.Arrays;
import java.util.zip.CRC32; import java.util.zip.CRC32;
@@ -33,11 +33,6 @@ public abstract class Message {
*/ */
public abstract int getSize(); 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 * 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(){ public byte[] getBuffer(){
return buffer; return buffer.array();
} }
/** /**
@@ -1,10 +1,7 @@
package seng302.server.messages; package seng302.server.messages;
import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.channels.Channels; import java.io.OutputStream;
import java.nio.channels.SocketChannel;
import java.nio.channels.WritableByteChannel;
public class RaceStartStatusMessage extends Message { public class RaceStartStatusMessage extends Message {
private final int MESSAGE_SIZE = 20; private final int MESSAGE_SIZE = 20;
@@ -32,15 +29,6 @@ public class RaceStartStatusMessage extends Message {
this.raceId = raceId; this.raceId = raceId;
setHeader(new Header(MessageType.RACE_START_STATUS, 1, (short) getSize())); 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(); allocateBuffer();
writeHeaderToBuffer(); writeHeaderToBuffer();
@@ -53,16 +41,11 @@ public class RaceStartStatusMessage extends Message {
writeCRC(); writeCRC();
rewind(); rewind();
if (outputStream == null){
return;
}
try{
outputStream.write(getBuffer());
}
catch (IOException e){
return;
}
} }
@Override
public int getSize() {
return MESSAGE_SIZE;
}
} }
@@ -1,7 +1,7 @@
package seng302.server.messages; package seng302.server.messages;
import java.io.IOException; import java.io.IOException;
import java.nio.channels.SocketChannel; import java.io.OutputStream;
import java.util.List; import java.util.List;
import java.util.zip.CRC32; import java.util.zip.CRC32;
@@ -47,22 +47,6 @@ public class RaceStatusMessage extends Message{
crc = new CRC32(); crc = new CRC32();
setHeader(new Header(MESSAGE_TYPE, (int) sourceId, (short) getSize())); 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(); allocateBuffer();
writeHeaderToBuffer(); writeHeaderToBuffer();
@@ -82,7 +66,14 @@ public class RaceStatusMessage extends Message{
writeCRC(); writeCRC();
rewind(); rewind();
outputStream.write(getBuffer());
} }
/**
* @return the size of this message in bytes
*/
@Override
public int getSize() {
return MESSAGE_BASE_SIZE + (20 * ((int) numBoatsInRace));
}
} }
@@ -1,12 +1,7 @@
package seng302.server.messages; package seng302.server.messages;
import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.io.OutputStream;
import java.nio.channels.Channels;
import java.nio.channels.SocketChannel;
import java.nio.channels.WritableByteChannel;
import java.util.zip.CRC32;
public class XMLMessage extends Message{ public class XMLMessage extends Message{
private final MessageType MESSAGE_TYPE = MessageType.XML_MESSAGE; private final MessageType MESSAGE_TYPE = MessageType.XML_MESSAGE;
@@ -35,20 +30,6 @@ public class XMLMessage extends Message{
sequence = sequenceNum; sequence = sequenceNum;
setHeader(new Header(MESSAGE_TYPE, 0x01, (short) getSize())); 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(); allocateBuffer();
writeHeaderToBuffer(); writeHeaderToBuffer();
@@ -63,7 +44,12 @@ public class XMLMessage extends Message{
writeCRC(); writeCRC();
rewind(); rewind();
}
outputStream.write(getBuffer()); /**
* @return The length of this message
*/
public int getSize(){
return MESSAGE_SIZE + content.length();
} }
} }