KOProject/ClientSessionThread.java

139 lines
5.1 KiB
Java

package com.collibra.server;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.UUID;
/**
* Every time a new client connects to the server a new thread is created for the client's session.
* The session stays active until the client times out or the client sends a disconnect message.
* @version 1.0
* @author Yordan Kirov
* @since 21/11/2018
*/
class ClientSessionThread extends Thread {
/** Socket used for communication between the server and the client. */
private final Socket clientSocket;
/** The time when the client has connected. */
private long startTime;
/** The name of the client that is retrieved after the initial communication. */
private String clientName = null;
/**
* Indicator whether the client session is still active or not.
* When it is made inactive the client gets disconnected.
*/
private boolean isSessionActive;
/** Universally unique identifier of the client session. */
private final String sessionId;
/**
* Constructor
* Initializes the start time of the connection.
* Sets the session to active.
* Generates a universally unique identifier of the client session.
* @param clientSocket the socket on which the client connects to the server.
*/
public ClientSessionThread(Socket clientSocket) {
System.out.println("Client connected.");
this.clientSocket = clientSocket;
this.startTime = System.currentTimeMillis();
this.isSessionActive = true;
this.sessionId = UUID.randomUUID().toString();
}
/**
* Initializes the communication between the server and the client.
* Sends a first message to the client.
* Sets the client name if the client sends it properly or waits to receive it.
* Takes all commands of the client and answers to them.
* When an error occurs the connection with the client is closed.
*/
public void run() {
PrintWriter out = null;
BufferedReader in = null;
try {
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
SimpleProtocol.sendFirstMessage(out, sessionId);
String inputLine;
while (isSessionActive && (inputLine = in.readLine()) != null) {
if (this.clientName == null) {
this.clientName = SimpleProtocol.retrieveClientName(out, inputLine);
} else {
acceptMessage(inputLine, out);
}
}
} catch (SocketTimeoutException se) {
System.out.println(this.clientName + " TIMED OUT!!!");
} catch (Exception e) {
e.printStackTrace();
} finally {
SimpleProtocol.sendGoodbyeMessage(out, this.clientName, startTime);
disconnect();
}
}
/**
* Accepts client messages and executes the commands according to the SimpleProtocol.
* @param clientMessage message coming from the client
* @param out the PrintWriter with which the server sends messages to the client.
*/
private void acceptMessage(String clientMessage, PrintWriter out) {
if ("BYE MATE!".equals(clientMessage)) {
this.isSessionActive = false;
return;
}
String serverMessage;
if (clientMessage.startsWith("ADD NODE ")) {
serverMessage = SimpleProtocol.addNode(clientMessage);
} else if (clientMessage.startsWith("ADD EDGE ")) {
serverMessage = SimpleProtocol.addEdge(clientMessage);
} else if (clientMessage.startsWith("REMOVE NODE ")) {
serverMessage = SimpleProtocol.removeNode(clientMessage);
} else if (clientMessage.startsWith("REMOVE EDGE ")) {
serverMessage = SimpleProtocol.removeEdge(clientMessage);
} else if (clientMessage.startsWith("SHORTEST PATH ")) {
serverMessage = SimpleProtocol.getShortestPath(clientMessage);
} else if (clientMessage.startsWith("CLOSER THAN ")) {
serverMessage = SimpleProtocol.getCloserThan(clientMessage);
} else {
serverMessage = SimpleProtocol.unsupportedCommand();
}
debugToConsole(clientMessage, serverMessage);
out.println(serverMessage);
}
private void debugToConsole(String clientMessage, String serverMessage) {
if (Server.DEBUG) {
System.out.println(">>>" + clientMessage);
System.out.println(serverMessage);
}
}
private void disconnect() {
System.out.println("Closing the connection: " + this.clientName);
try {
if (clientSocket != null) {
clientSocket.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}