Camkode
Camkode

Creating a Real-Time Chat Application with Flask and Socket.IO

Posted by Kosal

Creating a Real-Time Chat Application with Flask and Socket.IO

Real-time communication has become an integral part of modern web applications. In this tutorial, we'll walk through the process of building a real-time chat application using Flask, a lightweight web framework for Python, and Socket.IO, a library that enables real-time, bidirectional communication between web clients and servers.

Prerequisites: Before we begin, ensure you have Python installed on your system along with basic knowledge of Python and web development concepts.

Step 1: Setting Up the Environment:

Let's start by setting up our development environment. Open your terminal and create a new directory for your project. Inside the project directory, create a virtual environment to isolate your project's dependencies:

mkdir flask_chat_app
cd flask_chat_app
python3 -m venv venv

Activate the virtual environment:

  • On macOS/Linux:

    source venv/bin/activate
    
  • On Windows:

    venv\Scripts\activate
    

Install Flask and Flask-SocketIO using pip:

pip install Flask Flask-SocketIO

Step 2: Creating the Flask Application:

Now, let's create the Flask application. Inside your project directory, create a Python file named app.py. Open app.py and initialize your Flask app along with Socket.IO:

from flask import Flask, render_template
from flask_socketio import SocketIO

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your_secret_key'
socketio = SocketIO(app, cors_allowed_origins="*")

Step 3: Creating the HTML Template:

Next, create an HTML template for your chat interface. Create a file named index.html in your project directory and add the following code:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Real-Time Chat Application</title>
    <!-- Bootstrap CSS -->
    <link
      rel="stylesheet"
      href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
    />
    <!-- Custom CSS -->
    <style>
      #messages {
        list-style-type: none;
        padding: 0;
      }

      .message {
        margin-bottom: 10px;
        padding: 10px;
        border-radius: 5px;
      }

      .message.sent {
        background-color: #007bff;
        color: #fff;
        text-align: right;
      }

      .message.received {
        background-color: #f0f0f0;
        color: #000;
        text-align: left;
      }

      #message_input {
        width: 80%;
        margin-right: 10px;
      }

      #send {
        width: 18%;
      }
    </style>
  </head>
  <body>
    <div class="container mt-5">
      <div class="row">
        <div class="col-md-8 offset-md-2">
          <ul id="messages" class="p-3"></ul>
          <form id="form">
            <div class="input-group mb-3">
              <input
                type="text"
                id="message_input"
                class="form-control"
                placeholder="Type a message"
                aria-label="Type a message"
                aria-describedby="basic-addon2"
              />
              <div class="input-group-append">
                <button class="btn btn-primary" type="submit">Send</button>
              </div>
            </div>
          </form>
        </div>
      </div>
    </div>

    <!-- Bootstrap JS -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
    <!-- Socket.IO -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.2.0/socket.io.js"></script>

    <script>
      var socket = io();

      var form = document.getElementById("form");
      var input = document.getElementById("message_input");
      var sendButton = document.getElementById("send");

      form.addEventListener("submit", function (e) {
        e.preventDefault();
        if (input.value.trim() !== "") {
          socket.emit("message", {
            message: input.value,
            socket_id: socket.id,
          });
          input.value = "";
        }
      });

      socket.on("message", function (data) {
        var item = document.createElement("li");
        if (data.socket_id === socket.id) {
          item.classList.add("message", "sent");
          item.textContent = "You: " + data.message;
        } else {
          item.classList.add("message", "received");
          item.textContent = data.socket_id + ": " + data.message;
        }
        document.getElementById("messages").appendChild(item);
        window.scrollTo(0, document.body.scrollHeight);
      });
    </script>
  </body>
</html>

Step 4: Handling Socket.IO Events:

Define Socket.IO events in app.py to handle incoming and outgoing messages:

@app.route('/')
def index():
    return render_template('index.html')

@socketio.on('message')
def handle_message(data):
    message = data['message']
    socket_id = data['socket_id']
    print(f'Message from {socket_id}: {message}')
    socketio.emit('message', {'message': message, 'socket_id': socket_id})

Step 5: Running the Application:

Finally, run the Flask app:

if __name__ == '__main__':
    socketio.run(app, host='0.0.0.0', port=5000, debug=True)

Preview: preivew {823x616}

Conclusion: Congratulations! You have successfully built a real-time chat application using Flask and Socket.IO. This application serves as a foundation for more advanced features like user authentication, message persistence, and multiple chat rooms. Experiment with the code, explore additional functionalities, and unleash the full potential of real-time communication in your web applications. Happy coding!