Network Programming in Java - #9 - Chat System #4 - Client Disconnect Listener

Introduction: This tutorial is the ninth in my Java Network Programming using KryoNet series, or fourth in creating a chat client and server system, in which we are going to be handling disconnected clients. Previous: In the previous tutorial we created a way to receive and send messages through a new Packet2Message class to and from our server/client. The System: We are going to give the user a GUI to interact with the system - to send messages and see the currently connected members of the chat. When a client connects, add them to a list. Send incoming messages to everyone within the client list except the sender - or send them one back saying that it is received, as confirmation. This Tutorial: This tutorial we are going to be creating a listener to automatically remove clients from our connected list if they disconnect. The Listener: In our server we already have a listener to await incoming connections with data and handle them - packets, so lets add a disconnected method from the KryoNet Listener class...
  1. server.addListener(new Listener() {
  2. public void disconnected(Connection connection) {
  3. clientHandler.removeClient(connection);
  4. }
  5. public void received(Connection connection, Object object) {
  6. if (object instanceof Packet) {
  7. if (object instanceof Packet1Connect) {
  8. Packet1Connect con = (Packet1Connect) object;
  9. System.out.println("[CONNECTED] " + con.name);
  10. clientHandler.addClient(new CustomClient(con.name, connection));
  11. }else if(object instanceof Packet2Message) {
  12. Packet2Message mes = (Packet2Message) object;
  13. System.out.println("[RECEIVED] [" + clientHandler.getClient(connection).getUsername() + "] " + mes.message);
  14. }
  15. }
  16. }
  17. });
This will be ran whenever a client disconnects. We run a method we are yet to create in our clientHandler named removeClient and pass it the argument/parameter of Connection connection. Remove Client: So now we need to create the removeClient method in our clientHandler class that accepts a Connection variable...
  1. public void removeClient(Connection connection) {
  2. int index = 0;
  3. for (CustomClient c : this.clients) {
  4. if (c.getConnection().getID() == connection.getID()) {
  5. break;
  6. }else
  7. index++;
  8. }
  9. System.out.println("[INFO] Client removed with connection ID " + connection.getID() + ", " + getUsername(connection) + ".");
  10. this.clients.remove(index);
  11. }
So first we create a new integer variable named index with a default value of zero (0) then we iterate through each client in the clients list and check to see if the connection ID is the same as the disconnected connection ID. If it is, we break out of the if statement and for each loop, otherwise we increment index by one and try the next client within the connected clients list. Once we have found the client connection with the correct ID, we output to the console the information including the connection ID and the username of that connected client, then remove them from our connected list. GetUsername: We also need to create a new method named getUsername which we used in the previous method removeClient. This simply runs through each connected client within the list and compares connection IDs (again), if it finds the right one it returns the username, otherwise returns "unfound."...
  1. public String getUsername(Connection connection) {
  2. for (CustomClient c : this.clients) {
  3. if (c.getConnection().getID() == connection.getID())
  4. return c.getUsername();
  5. }
  6. return "unfound";
  7. }
Checking The List: Now we are going to create a simple while loop to output each connected client within the clientHandler list's username to the console, just to see that it is working correctly... -Insert under the listener on the server main class-
  1. while (true) {
  2. System.out.println("===BEGIN CLIENT LIST===");
  3. for (CustomClient c : clientHandler.clients) {
  4. System.out.println(c.getUsername());
  5. }
  6. System.out.println("===END CLIENT LIST===");
  7. try {
  8. Thread.sleep(5000);
  9. } catch (InterruptedException e) {
  10. e.printStackTrace();
  11. }
  12. }
-You can leave this in once the project is finished if you wish.- As you can see, we output each clients username, then wait for 5000 milliseconds (5 seconds) before re-looping.

Add new comment