Java Doc Server && ServerConnectionHandler
This commit is contained in:
		
							parent
							
								
									84e59effec
								
							
						
					
					
						commit
						73dcfb5058
					
				| 
						 | 
					@ -10,7 +10,15 @@ import java.util.Map;
 | 
				
			||||||
import java.util.concurrent.locks.Condition;
 | 
					import java.util.concurrent.locks.Condition;
 | 
				
			||||||
import java.util.concurrent.locks.ReentrantLock;
 | 
					import java.util.concurrent.locks.ReentrantLock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * This Class represents a Server. The user can start the programm with the port number as a argument.
 | 
				
			||||||
 | 
					 * If no argument has been set the {@link NetworkHandler#DEFAULT_PORT} is used as port number.
 | 
				
			||||||
 | 
					 * After initialising the server:
 | 
				
			||||||
 | 
					 * 1. Starts a Socketserver using the logic given in {@link NetworkHandler.NetworkServer#createServer()}
 | 
				
			||||||
 | 
					 * 2. The server starts to listen for incoming connection using the Logic given in {@link NetworkHandler.NetworkServer#waitForConnection()}
 | 
				
			||||||
 | 
					 * 3. New conections will be atached to a Connectionhandler: {@link ServerConnectionHandler} and placed in a Map containing all active connections {@link Server#connections}
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
public class Server {
 | 
					public class Server {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Server connection
 | 
					    // Server connection
 | 
				
			||||||
| 
						 | 
					@ -57,6 +65,11 @@ public class Server {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The Constructor to create a new instance.
 | 
				
			||||||
 | 
					     * @param serverPort to listen for incoming connections.
 | 
				
			||||||
 | 
					     * @throws IOException thrown if an I/O error occurs when opening the socket.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public Server(int serverPort) throws IOException {
 | 
					    public Server(int serverPort) throws IOException {
 | 
				
			||||||
        // Open server connection
 | 
					        // Open server connection
 | 
				
			||||||
        System.out.println("Create server connection");
 | 
					        System.out.println("Create server connection");
 | 
				
			||||||
| 
						 | 
					@ -64,6 +77,10 @@ public class Server {
 | 
				
			||||||
        System.out.println("Listening on " + networkServer.getHostAddress() + ":" + networkServer.getHostPort());
 | 
					        System.out.println("Listening on " + networkServer.getHostAddress() + ":" + networkServer.getHostPort());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * With this methode the instance waits for incoming connections. If a client tries to connect to the server.
 | 
				
			||||||
 | 
					     * The connection will be registered in the connection registry if successful.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    private void start() {
 | 
					    private void start() {
 | 
				
			||||||
        ReentrantLock mutex = new ReentrantLock();
 | 
					        ReentrantLock mutex = new ReentrantLock();
 | 
				
			||||||
        Condition nameComplete = mutex.newCondition();
 | 
					        Condition nameComplete = mutex.newCondition();
 | 
				
			||||||
| 
						 | 
					@ -104,6 +121,9 @@ public class Server {
 | 
				
			||||||
        System.out.println("Server Stopped.");
 | 
					        System.out.println("Server Stopped.");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * This method will stop the serversocket.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public void terminate() {
 | 
					    public void terminate() {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            System.out.println("Close server port.");
 | 
					            System.out.println("Close server port.");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,31 @@ import java.util.concurrent.locks.Condition;
 | 
				
			||||||
import java.util.concurrent.locks.ReentrantLock;
 | 
					import java.util.concurrent.locks.ReentrantLock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * This class represents the connection between the server and a client and offers the serverside logic.
 | 
				
			||||||
 | 
					 * The ServerConnectionHandler receives data send from the client aswell as sends data to the client.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The ServeConnectionHandler offers following functionality:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Evaluating connection attempts from a client by:
 | 
				
			||||||
 | 
					 * 1. Checks if Username is valid (Not used)
 | 
				
			||||||
 | 
					 * 2. Saves Username in {@link ServerConnectionHandler#userName}
 | 
				
			||||||
 | 
					 * 3. Saves the connection in the {@link ServerConnectionHandler#connectionRegistry}
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Processes disconnections from a client by:
 | 
				
			||||||
 | 
					 * 1. Removing the connection from the {@link ServerConnectionHandler#connectionRegistry}
 | 
				
			||||||
 | 
					 * 2. Terminates the socket by calling {@link NetworkHandler.NetworkConnection#close()}
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Processes Messages send from a client by:
 | 
				
			||||||
 | 
					 * 1. Evaluating the reciever by differentiating between broadcast or unicast.
 | 
				
			||||||
 | 
					 * 2. Sending the message accordingly.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * To use this class, start a new instance and start it in a thread.
 | 
				
			||||||
 | 
					 * To constructor needs following parameter:
 | 
				
			||||||
 | 
					 * 1. {@link ch.zhaw.pm2.multichat.protocol.NetworkHandler.NetworkConnection} representing the socket connection between server and client
 | 
				
			||||||
 | 
					 * 2. {@link Map<String,ServerConnectionHandler>} registry to check for all active connections
 | 
				
			||||||
 | 
					 * 3. {@link ReentrantLock @link Condition} to lock server thread to evaluate connection.
 | 
				
			||||||
 | 
					 * */
 | 
				
			||||||
public class ServerConnectionHandler extends ConnectionHandler implements Runnable{
 | 
					public class ServerConnectionHandler extends ConnectionHandler implements Runnable{
 | 
				
			||||||
    private static final AtomicInteger connectionCounter = new AtomicInteger(0);
 | 
					    private static final AtomicInteger connectionCounter = new AtomicInteger(0);
 | 
				
			||||||
    private final int connectionId = connectionCounter.incrementAndGet();
 | 
					    private final int connectionId = connectionCounter.incrementAndGet();
 | 
				
			||||||
| 
						 | 
					@ -29,11 +53,21 @@ public class ServerConnectionHandler extends ConnectionHandler implements Runnab
 | 
				
			||||||
    private String userName = "Anonymous-"+connectionId;
 | 
					    private String userName = "Anonymous-"+connectionId;
 | 
				
			||||||
    private State state = NEW;
 | 
					    private State state = NEW;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Called when runnable gets started in a thread.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void run() {
 | 
					    public void run() {
 | 
				
			||||||
        startReceiving();
 | 
					        startReceiving();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Constructor to intitialize the connection
 | 
				
			||||||
 | 
					     * @param connection representing the socket connection between server and clinet
 | 
				
			||||||
 | 
					     * @param registry map containing all active connections between server and clients
 | 
				
			||||||
 | 
					     * @param mutex to lock thread
 | 
				
			||||||
 | 
					     * @param nameComplete condition to call threads
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public ServerConnectionHandler(NetworkHandler.NetworkConnection<String> connection,
 | 
					    public ServerConnectionHandler(NetworkHandler.NetworkConnection<String> connection,
 | 
				
			||||||
                                   Map<String,ServerConnectionHandler> registry, ReentrantLock mutex, Condition nameComplete) {
 | 
					                                   Map<String,ServerConnectionHandler> registry, ReentrantLock mutex, Condition nameComplete) {
 | 
				
			||||||
        super();
 | 
					        super();
 | 
				
			||||||
| 
						 | 
					@ -45,14 +79,26 @@ public class ServerConnectionHandler extends ConnectionHandler implements Runnab
 | 
				
			||||||
        this.nameComplete = nameComplete;
 | 
					        this.nameComplete = nameComplete;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return the username of the connected client
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public String getUserName() {
 | 
					    public String getUserName() {
 | 
				
			||||||
        return this.userName;
 | 
					        return this.userName;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return state of the connection. Poosible states are see {@link ch.zhaw.pm2.multichat.protocol.ConnectionHandler.State}
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public State getState() {
 | 
					    public State getState() {
 | 
				
			||||||
        return state;
 | 
					        return state;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * This methods runs in a whileloop as long as the socket between server and client is available
 | 
				
			||||||
 | 
					     * and the connection State is not ERROR.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    private void startReceiving() {
 | 
					    private void startReceiving() {
 | 
				
			||||||
            System.out.println("Starting Connection Handler for new User");
 | 
					            System.out.println("Starting Connection Handler for new User");
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
| 
						 | 
					@ -83,6 +129,9 @@ public class ServerConnectionHandler extends ConnectionHandler implements Runnab
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * This method will call {@link NetworkHandler.NetworkConnection#close()} to close the Socket.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    private void stopReceiving() {
 | 
					    private void stopReceiving() {
 | 
				
			||||||
        System.out.println("Closing Connection Handler for " + userName);
 | 
					        System.out.println("Closing Connection Handler for " + userName);
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
| 
						 | 
					@ -95,6 +144,17 @@ public class ServerConnectionHandler extends ConnectionHandler implements Runnab
 | 
				
			||||||
        System.out.println("Closed Connection Handler for " + userName);
 | 
					        System.out.println("Closed Connection Handler for " + userName);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * This method gets called when socket recieves data. The method checks for the data type and reacts accordingly
 | 
				
			||||||
 | 
					     * If data type:
 | 
				
			||||||
 | 
					     * 1. Connect => checks if username is valid. if valid sends response to client with confirmation.
 | 
				
			||||||
 | 
					     *  If username not valid quits connection by changing status to ERROR.
 | 
				
			||||||
 | 
					     * 2. Confirm => Server should not recieve this kind of message. STDOUT informs about it.
 | 
				
			||||||
 | 
					     * 3. Disconnect => Disconnects connection by removing connection from registry and calling method to terminate socket.
 | 
				
			||||||
 | 
					     * 4. Message => Checks if broadcast or unicast. Sends data accordingly
 | 
				
			||||||
 | 
					     * 5. Error => STDERR message
 | 
				
			||||||
 | 
					     * @param data recieved by the server
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    private void processData(String data)  {
 | 
					    private void processData(String data)  {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            Scanner scanner = new Scanner(data);
 | 
					            Scanner scanner = new Scanner(data);
 | 
				
			||||||
| 
						 | 
					@ -125,6 +185,12 @@ public class ServerConnectionHandler extends ConnectionHandler implements Runnab
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * This method is called by method {@link ServerConnectionHandler#processData(String)}
 | 
				
			||||||
 | 
					     * Checks if username is valid. if valid sends response to client with confirmation.
 | 
				
			||||||
 | 
					     * @param sender of the payload
 | 
				
			||||||
 | 
					     * @throws ChatProtocolException if username not valid
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    private void caseConnect(String sender) throws ChatProtocolException {
 | 
					    private void caseConnect(String sender) throws ChatProtocolException {
 | 
				
			||||||
        if (this.state != NEW) throw new ChatProtocolException("Illegal state for connect request: " + state);
 | 
					        if (this.state != NEW) throw new ChatProtocolException("Illegal state for connect request: " + state);
 | 
				
			||||||
        if (sender.isBlank()) sender = this.userName;
 | 
					        if (sender.isBlank()) sender = this.userName;
 | 
				
			||||||
| 
						 | 
					@ -141,7 +207,7 @@ public class ServerConnectionHandler extends ConnectionHandler implements Runnab
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        mutex.lock();
 | 
					        mutex.lock();
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            this.userName = sender.toString();
 | 
					            this.userName = sender;
 | 
				
			||||||
            nameComplete.signal();
 | 
					            nameComplete.signal();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        finally {
 | 
					        finally {
 | 
				
			||||||
| 
						 | 
					@ -152,6 +218,11 @@ public class ServerConnectionHandler extends ConnectionHandler implements Runnab
 | 
				
			||||||
        this.state = CONNECTED;
 | 
					        this.state = CONNECTED;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * This method is called by method {@link ServerConnectionHandler#processData(String)}
 | 
				
			||||||
 | 
					     * Disconnects connection by removing connection from registry and calling method {@link ServerConnectionHandler#stopReceiving()} to terminate socket.
 | 
				
			||||||
 | 
					     * @throws ChatProtocolException if state allready DISCONNECTED.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    private void caseDisconnect() throws ChatProtocolException {
 | 
					    private void caseDisconnect() throws ChatProtocolException {
 | 
				
			||||||
        if (state == DISCONNECTED)
 | 
					        if (state == DISCONNECTED)
 | 
				
			||||||
            throw new ChatProtocolException("Illegal state for disconnect request: " + state);
 | 
					            throw new ChatProtocolException("Illegal state for disconnect request: " + state);
 | 
				
			||||||
| 
						 | 
					@ -163,6 +234,15 @@ public class ServerConnectionHandler extends ConnectionHandler implements Runnab
 | 
				
			||||||
        this.stopReceiving();
 | 
					        this.stopReceiving();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * This method is called by method {@link ServerConnectionHandler#processData(String)}
 | 
				
			||||||
 | 
					     * Checks if broadcast or unicast. Sends data accordingly
 | 
				
			||||||
 | 
					     * @param sender who sent data
 | 
				
			||||||
 | 
					     * @param reciever to recieve data
 | 
				
			||||||
 | 
					     * @param type of message
 | 
				
			||||||
 | 
					     * @param payload data to transmit
 | 
				
			||||||
 | 
					     * @throws ChatProtocolException if state not equal to CONNECT
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    private void caseMessage(String sender, String reciever, String type, String payload) throws ChatProtocolException{
 | 
					    private void caseMessage(String sender, String reciever, String type, String payload) throws ChatProtocolException{
 | 
				
			||||||
        if (state != CONNECTED) throw new ChatProtocolException("Illegal state for message request: " + state);
 | 
					        if (state != CONNECTED) throw new ChatProtocolException("Illegal state for message request: " + state);
 | 
				
			||||||
        if (USER_ALL.equals(reciever)) {
 | 
					        if (USER_ALL.equals(reciever)) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue