139 lines
5.1 KiB
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();
|
|
}
|
|
}
|
|
}
|