• We just launched and are currently in beta. Join us as we build and grow the community.

Advertise Here

Advertise Here

Advertise Here

Chat System - Client Unique Usernames

aaddddas

Satire Specialist
A Rep
0
0
0
Rep
0
A Vouches
0
0
0
Vouches
0
Posts
138
Likes
68
Bits
2 MONTHS
2 2 MONTHS OF SERVICE
LEVEL 1 100 XP
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:

  1. package

    Packets

    ;

  2. public

    class

    Packet3UsernameReq extends

    Packet{
  3. public

    String

    username;
  4. }

Res:

  1. package

    Packets

    ;

  2. public

    class

    Packet4UsernameRes extends

    Packet{
  3. public

    boolean

    bool;
  4. }

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...

  1. public

    void

    connect(

    Client client)

    {
  2. System

    .out

    .println

    (

    "Enter your username for the new chat room... "

    )

    ;
  3. Scanner userScan =

    new

    Scanner(

    System

    .in

    )

    ;
  4. while

    (

    true

    )

    {
  5. String

    loggedInUsername =

    userScan.nextLine

    (

    )

    ;
  6. Packet3UsernameReq req =

    new

    Packet3UsernameReq(

    )

    ;
  7. req.username

    =

    loggedInUsername;
  8. client.sendTCP

    (

    req)

    ;
  9. while

    (

    !

    userServerRes)

    {
  10. try

    {
  11. System

    .out

    .println

    (

    "Sleeping..."

    )

    ;
  12. Thread

    .sleep

    (

    500

    )

    ;
  13. }

    catch

    (

    Exception

    ex)

    {

    }
  14. }
  15. System

    .out

    .println

    (

    "+ "

    +

    userServerAvailable)

    ;
  16. if

    (

    userServerAvailable)

    {
  17. System

    .out

    .println

    (

    "That username is already taken. Please enter a new one... "

    )

    ;
  18. userServerRes =

    false

    ;

    //Reset global booleans used for server username response
  19. }

    else

    {

    //false=available
  20. System

    .out

    .println

    (

    "Connecting..."

    )

    ;
  21. Packet1Connect con =

    new

    Packet1Connect(

    )

    ;
  22. con.name

    =

    loggedInUsername;
  23. client.sendTCP

    (

    con)

    ;
  24. System

    .out

    .println

    (

    "Connected as "

    +

    loggedInUsername)

    ;
  25. userServerRes =

    false

    ;

    //Reset global booleans used for server username response
  26. break

    ;
  27. }
  28. }
  29. }

In the method we use a couple of global variables, create these under the initial class line...

  1. boolean

    userServerRes =

    false

    ;
  2. boolean

    userServerAvailable =

    false

    ;

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..

  1. connect(

    client)

    ;

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...

  1. else

    if

    (

    object instanceof

    Packet3UsernameReq)

    {
  2. Packet3UsernameReq packet =

    (

    Packet3UsernameReq)

    object;
  3. boolean

    userExists =

    clientHandler.userExists

    (

    packet.username

    )

    ;
  4. Packet4UsernameRes resPacket =

    new

    Packet4UsernameRes(

    )

    ;
  5. resPacket.bool

    =

    userExists;
  6. connection.sendTCP

    (

    resPacket)

    ;
  7. }

Client Handler userExists method...

  1. public

    boolean

    userExists(

    String

    username)

    {
  2. // Return true if user Exists, false if the username is available.
  3. for

    (

    CustomClient c :

    this

    .clients

    )

    {
  4. if

    (

    c.getUsername

    (

    )

    .toLowerCase

    (

    )

    .equals

    (

    username.toLowerCase

    (

    )

    )

    )
  5. return

    true

    ;

    // Username exists.
  6. }
  7. return

    false

    ;

    //Username available.
  8. }

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...

  1. server.getKryo

    (

    )

    .register

    (

    Packet3UsernameReq.class

    )

    ;
  2. server.getKryo

    (

    )

    .register

    (

    Packet4UsernameRes.class

    )

    ;

And:

  1. client.getKryo

    (

    )

    .register

    (

    Packet3UsernameReq.class

    )

    ;
  2. client.getKryo

    (

    )

    .register

    (

    Packet4UsernameRes.class

    )

    ;

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...

  1. else

    if

    (

    object instanceof

    Packet4UsernameRes)

    {
  2. Packet4UsernameRes res =

    (

    Packet4UsernameRes)

    object;
  3. userServerAvailable =

    res.bool

    ;

    //Original bool is false if username is available, revert this to true for the variable.
  4. userServerRes =

    true

    ;
  5. System

    .out

    .println

    (

    "Username response received."

    )

    ;
  6. }

 

452,496

342,733

342,741

Top