mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 06:18:44 +00:00
WIP: Worked on new server thread class that would create and store multiple THREADS of connections. Researched Authorative server structures
tags: #story[1047]
This commit is contained in:
@@ -3,14 +3,10 @@ package seng302.gameServer;
|
||||
import seng302.models.Player;
|
||||
import seng302.models.Yacht;
|
||||
import seng302.server.messages.*;
|
||||
import seng302.server.simulator.Boat;
|
||||
import seng302.server.simulator.Simulator;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketOption;
|
||||
import java.net.SocketOptions;
|
||||
import java.nio.channels.ServerSocketChannel;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.util.*;
|
||||
@@ -360,41 +356,42 @@ public class GameServerThread implements Runnable, Observer, ClientConnectionDel
|
||||
@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()));
|
||||
broadcast(m);
|
||||
} catch (IOException e) {
|
||||
serverLog("Couldn't send a boat status message", 3);
|
||||
return;
|
||||
}
|
||||
catch (NullPointerException e){
|
||||
e.printStackTrace();
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
// /* 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()));
|
||||
// broadcast(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();
|
||||
// }
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void terminateGame() {
|
||||
try {
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
package seng302.gameServerWithThreading;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
|
||||
/**
|
||||
* 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 ServerThread extends Thread {
|
||||
|
||||
private static final Integer MAX_ID_ATTEMPTS = 10;
|
||||
|
||||
private InputStream is;
|
||||
private OutputStream os;
|
||||
private Socket socket;
|
||||
|
||||
private Boolean userIdentified = false;
|
||||
private Boolean connected = true;
|
||||
private Boolean updateClient = true;
|
||||
|
||||
public ServerThread(Socket socket) {
|
||||
this.socket = socket;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
is = socket.getInputStream();
|
||||
os = socket.getOutputStream();
|
||||
} catch (IOException e) {
|
||||
System.out.println("IO error in server thread upon grabbing streams");
|
||||
}
|
||||
|
||||
threeWayHandshake();
|
||||
|
||||
// TODO: 13/07/17 wmu16 - Some way of knowing if the client is still connected. perhaps when we read disconnect message switch this bool?
|
||||
while (connected) {
|
||||
|
||||
//Perform a read and update game state
|
||||
try {
|
||||
Integer userInput = is.read();
|
||||
} catch (IOException e) {
|
||||
System.out.println("IO error in server thread upon reading input stream");
|
||||
}
|
||||
|
||||
|
||||
//Perform a write if it is time to as delegated by the ServerThreadHandler
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
closeSocket();
|
||||
|
||||
}
|
||||
|
||||
public void updateClient() {
|
||||
updateClient = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tries to confirm the connection just accepted.
|
||||
* Sends ID, expects that ID echoed for confirmation,
|
||||
* 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
|
||||
*/
|
||||
private void threeWayHandshake() {
|
||||
// TODO: 13/07/17 Finish using AC35
|
||||
// Integer playerID = GameState.getUniquePlayerID();
|
||||
// Integer confirmationID = null;
|
||||
// Integer identificationAttempt = 0
|
||||
// while (!userIdentified) {
|
||||
// os.write(playerID); //Send out new ID looking for echo
|
||||
// confirmationID = is.read();
|
||||
// if (playerID == idConfirmation) { //ID is echoed back. Connection is a client
|
||||
// os.write( some determined confirmation message ); //Confirm to client
|
||||
// GameState.addPlayer(new Player(playerID, this)); //Create a player in game state for client
|
||||
// userIdentified = true;
|
||||
// } else if (identificationAttempt > MAX_ID_ATTEMPTS) { //No response. not a client. tidy up and go home.
|
||||
// closeSocket();
|
||||
// return;
|
||||
// }
|
||||
// identificationAttempt++;
|
||||
// }
|
||||
}
|
||||
|
||||
public void closeSocket() {
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e) {
|
||||
System.out.println("IO error in server thread upon trying to close socket");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package seng302.gameServerWithThreading;
|
||||
|
||||
import seng302.gameServer.GameStages;
|
||||
import seng302.gameServer.GameState;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* A class describing the overall server, which creates and collects server threads for each client
|
||||
* Created by wmu16 on 13/07/17.
|
||||
*/
|
||||
public class ServerThreadHandler extends Thread {
|
||||
|
||||
private static final int PORT = 4950;
|
||||
private static final Integer MAX_NUM_PLAYERS = 10;
|
||||
|
||||
private ServerSocket serverSocket = null;
|
||||
private Socket socket;
|
||||
private ArrayList<ServerThread> serverThreads = new ArrayList<>();
|
||||
|
||||
public ServerThreadHandler() {
|
||||
try {
|
||||
serverSocket = new ServerSocket(PORT);
|
||||
} catch (IOException e) {
|
||||
System.out.println("IO error in server thread handler upon trying to make new server socket");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void run() {
|
||||
//You should handle interrupts in some way, so that the thread won't keep on forever if you exit the app.
|
||||
while (!isInterrupted()) {
|
||||
try {
|
||||
Thread.sleep(1000 / 60); //60 times per second we should calculate the game state
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (GameState.getCurrentStage() == GameStages.LOBBYING && GameState.getPlayers().size() < MAX_NUM_PLAYERS) {
|
||||
try {
|
||||
socket = serverSocket.accept();
|
||||
} catch (IOException e) {
|
||||
System.out.println("IO error in server thread handler upon trying to accept connection");
|
||||
}
|
||||
ServerThread thread = new ServerThread(socket);
|
||||
serverThreads.add(thread);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
updateClients();
|
||||
}
|
||||
|
||||
try {
|
||||
serverSocket.close();
|
||||
} catch (IOException e) {
|
||||
System.out.println("IO error in server thread handler upon closing socket");
|
||||
}
|
||||
}
|
||||
|
||||
public void updateClients() {
|
||||
for (ServerThread serverThread : serverThreads) {
|
||||
serverThread.updateClient();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user