Real-Time Chat Application In Python
Tags: python, programming, tutorial
Published: 2021-12-07 16:01:18

{% youtube cV-syT1fO2c %}
What's up Pythoneers ! This is Vishesh Dvivedi and in this blog post I am gonna show you how you can create a real-time chat application in python, using tkinter module and socket programming.

This blog will discuss about socket programming, tkinter module and how you can integrate them both.

About the application
----------------
The repository of this application consists of two python files, server.py and client.py. server.py is the script that runs the server, which all the clients will use to communicate to each other. And client.py will be used by the client to connect to server and send messages to other clients.

So we will start off by server.py script

Creating server.py
------------------
First off, we will import all the required modules of server.py

    import socket
    import threading

We would need socket module to communicate with clients and threading module to create a thread that would keep listening for messages from clients.

Next we will set up some variables

    HOST = '127.0.0.1'
    PORT = 1234 
    LISTENER_LIMIT = 5
    active_clients = []

HOST and PORT here determines the host and port at which the server will run, LISTENER_LIMIT stores the amount of clients that will be able to connect to a server at a time. And finally, active_clients will store all the users that will be connected to the server at any instance

Next we will create the listen_for_messages function

    def listen_for_messages(client, username):

        while 1:

            message = client.recv(2048).decode('utf-8')
            if message != '':
            
                final_msg = username + '~' + message
                send_messages_to_all(final_msg)

            else:
                print(f"The message send from client {username} is 
    empty")

This function will keep listening for messages from the connected clients. In case if it received a message, it will call the send_message_to_all function to send the received message to all currently connected clients.

Next we create the send_message_to_client function

    def send_message_to_client(client, message):

        client.sendall(message.encode())

This function is used to send message to a single client

Next we create the send_message_to_all function

    def send_messages_to_all(message):
    
        for user in active_clients:

            send_message_to_client(user[1], message)

This function will send a message to all connected clients by calling the send_message function for each connected client.

Next we create the client_handler function

    def client_handler(client):
    
        # Server will listen for client message that will
        # Contain the username
        while 1:

            username = client.recv(2048).decode('utf-8')
            if username != '':
                active_clients.append((username, client))
                prompt_message = "SERVER~" + f"{username} added to 
    the chat"
                send_messages_to_all(prompt_message)
                break
            else:
                print("Client username is empty")

        threading.Thread(target=listen_for_messages, args=(client, 
    username, )).start()

This function will use the client object (explained later in this blog) which we get when we connect to a client, to get username from a client, add the client to the list of active clients, and start a listener thread which will keep listening for new messages from the client.
Note: This function is also executed as a thread, for each new connected client.

    def main():

        server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)


        try:
            server.bind((HOST, PORT))
            print(f"Running the server on {HOST} {PORT}")
        except:
            print(f"Unable to bind to host {HOST} and port 
    {PORT}")

        server.listen(LISTENER_LIMIT)

        while 1:

            client, address = server.accept()
        print(f"Successfully connected to client {address[0]} {address[1]}")

        threading.Thread(target=client_handler, args=(client, )).start()


    if __name__ == '__main__':
        main()

And finally we have the main function, which performs the work of: 

1. Creating a socket (that acts as the server)
2. Binding IP and Port to the server
3. Setting up listener limit
4. Accept any upcoming connection from clients
5. Calling the client handler for any new connected client

That's all for the server side code, The server side code is a bit long to explain in a single blog, so I have created this playlist on YouTube, where I explain all the code, both server and client side code. So do check out this playlist to understand the client side code as well.

Link to playlist: [How To Create A Real-Time Chat App In Python Using Socket Programming](https://www.youtube.com/playlist?list=PLIw91yhFTTdJ2CDjOptoF-ddXbw7wmet-)