Chat System - Client Unique Usernames
Submitted by GeePee on Wednesday, March 11, 2015 - 11:44.
Introduction:
This tutorial is the eleventh in my Java Network Programming using KryoNet series, or sixth in creating a chat client and server system, in which we are going to be ensuring that no two clients have the same username.
Previous:
In the previous tutorial we created a way to circulate any incoming messages to the server to the rest of the clients.
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:
Instead of just sending one PacketConnect from the client to the server, we are going to loop this until the username is not currently connected to the server through an other client.
Packets:
First we are going to create two new packets; Username3Req and Username4Res.
Request will contain the username to check with the server if the username exists. Res will be sent from the server as a response to the clients request packet stating whether the username is available or not.
Req:
Res:
Copy the packets to both projects Packets packages.
Client:
Now we want to edit the client to loop the connection and allow username input from the user...
In the method we use a couple of global variables, create these under the initial class line...
Then in the constructor where we used to have the four lines of PacketConnect (make sure the listener is above this connect call), replace it with running the new method..
This code will loop until the global variables are set correctly where the username is available. We use Thread.sleep(500) to sleep the program for half a second (500ms) while the server response boolean variable in the global scope is false because we do not yet have a response and so we are unable to check whether the username is available or not through the second boolean global variable and we don't want to spam the application with constant running.
Server Listener:
Now we want to handle the Packet from the server listener. First we make sure we are receiving a username request, then we run a method from our ClientHandler (we create this in a second) to return whether the username exists or not, with that information we reply with a UsernameRes (response) packet...
Client Handler userExists method...
Class Registering:
We also need to register the new classes in both the client and server. Put this under the other class registries we have already - TIP: Make sure the client and server registers are in the same order to avoid serialisation errors...
And:
Client Listener:
Finally we need to create our client listener. This will listen out for the username response packet and set the global variables accordingly which in turn will trigger the connect while loop to break (stop sleeping for 500ms) and continue with the attempted login...
- package Packets;
- public class Packet3UsernameReq extends Packet{
- }
- package Packets;
- public class Packet4UsernameRes extends Packet{
- public boolean bool;
- }
- public void connect(Client client) {
- while (true) {
- Packet3UsernameReq req = new Packet3UsernameReq();
- req.username = loggedInUsername;
- client.sendTCP(req);
- while (!userServerRes) {
- try {
- }
- if (userServerAvailable) {
- userServerRes = false; //Reset global booleans used for server username response
- }else{ //false=available
- Packet1Connect con = new Packet1Connect();
- con.name = loggedInUsername;
- client.sendTCP(con);
- userServerRes = false; //Reset global booleans used for server username response
- break;
- }
- }
- }
- boolean userServerRes = false;
- boolean userServerAvailable = false;
- connect(client);
- else if(object instanceof Packet3UsernameReq) {
- Packet3UsernameReq packet = (Packet3UsernameReq) object;
- boolean userExists = clientHandler.userExists(packet.username);
- Packet4UsernameRes resPacket = new Packet4UsernameRes();
- resPacket.bool = userExists;
- connection.sendTCP(resPacket);
- }
- // Return true if user Exists, false if the username is available.
- for (CustomClient c : this.clients) {
- if (c.getUsername().toLowerCase().equals(username.toLowerCase()))
- return true; // Username exists.
- }
- return false; //Username available.
- }
- server.getKryo().register(Packet3UsernameReq.class);
- server.getKryo().register(Packet4UsernameRes.class);
- client.getKryo().register(Packet3UsernameReq.class);
- client.getKryo().register(Packet4UsernameRes.class);
- else if(object instanceof Packet4UsernameRes) {
- Packet4UsernameRes res = (Packet4UsernameRes) object;
- userServerAvailable = res.bool; //Original bool is false if username is available, revert this to true for the variable.
- userServerRes = true;
- }
Add new comment
- 67 views