loading...

Building a messaging server from scratch. (Java)

justhere profile image yas ・2 min read

This requires you have good understanding of
Java,
ServerSocket,
ClientSocket.

I was motivated to build it, when i couldn't understand how modern app servers scales to millions of connections with single instance. So i started working on it. I couldn't get much help from internet when i started building, so writing this documentation...

Jumping straight at code.

This is the main class where the ConcurrentServer will start running.

class ConcurrentServer{
     public static void main(String[] arg) throws IOException, InterruptedException
     {
            int port;
            if(arg.length == 0){
              port = 8080;
            }
            else{
              port = Integer.parseInt(arg[0]);
            }

            new ConcurrentServer().start(port);
     }
}

Wait a sec....
Remember this List<User> clients here. It plays an important role.

public class Shared {

    public static List<User> clients = new ArrayList<>();

    public static int count= 0;

    private Shared(){

    }
}

When a new user is connected to the server, the connection object is pushed to the client list in Shared class (see below).

The User class below extends from ClientSocket.

public ConcurrentServer{
    public static void main.....
    .
    .
    .
    .

    public void start(int port) throws IOException, InterruptedException{   
        try(ServerSocket server = new ServerSocket(port)){

            Thread channelReaderThread = new Thread(channelReader);
            channelReaderThread.start();

            while(ALWAYS_RUNNING){
                User client = new User(server.accept());
                Shared.clients.add(client);
            }
        }
    }   
}

Next we read the user messages which might pop up at any time.

private void process()
{
    int maxSize = Shared.clients.size();

    for(int i = 0 ; i < maxSize ; i++)
    {
        User user = Shared.clients.get(i);

        queryClient(user, i);
    }
}

private void queryClient(User user,int index)
{
    InputStream inputStream = user.getInputStream();

    if( inputStream.available() <= 0 )
    {
        return;
    }

    ConnectedBy connection = user.getConnectionType();

    connection.handle(user);
}

Remember this guy Shared.clients, this is an array where pushed the connected users in main thread.

The process method above is triggered run every 100ms. Java provides a method called inputStream.available(), if user sends any message, inputStream.available() will > 0. Thats the time, we can read the message from the inputStream.


Once you are able to read message and as you already have all the clientConnections in Shared.clients you can iterate it and send the incoming message to all clients in it.

Hence you have a functioning messaging application.


It is tested with a few thousand parallel connections, it delivers messages most of the time.
But Caution.
There are occasions when messages are dropped, i could not figure out yet, why these messages are dropping. So any help would be highly appreciated.

Any one who understands or didn't understand it, do comment, i would be highly interested to reach out.

Source Code. https://github.com/SrikanthYashaswi/messenger

Discussion

pic
Editor guide