Milky Way: Chat App
This project is a real-time chat application designed to provide seamless communication. Here’s a breakdown of its architecture and key features.
Architecture Overview
- Flask: Handles the backend.
- Socket.IO: Enables real-time, bidirectional communication.
- Docker: Containerizes the application.
- Nginx: Manages incoming traffic and proxies requests to Flask.
- Ansible: Automates deployments.
Lifecycle of a Message
User Authentication: Users sign up and log in.
Joining the Chat: Authenticated users are redirected to the chat page. The chat page includes the Socket.IO client for real-time communication.
@socketio.on("connect", namespace="/chat")
def on_connect():
if current_user.is_authenticated:
current_app.redis.set(f"user_online_{current_user.id}", "online", ex=600)
update_friends_about_status(current_user.id, True)
join_room(str(current_user.id))
Sending a Message:
- The user types a message and clicks send.
- The message is sent to the server using Socket.IO.
- The server saves the message to the database and sends it to the recipient.
Receiving a Message:
- The recipient's browser listens for new messages using Socket.IO.
- When a message arrives, it's displayed in the chat log.
Tracking Online Status
To track online status, we use Socket.IO events:
- When a user connects, they join a "room" associated with their user ID.
- The server keeps track of users who are connected.
- When a user disconnects, they leave the room, and their status is updated.
Managing Unread Messages
Unread messages are tracked using Redis:
- Each time a message is sent, it increments an unread counter for the recipient.
- When the recipient opens the chat, the counter resets to zero.
- This ensures users know how many messages they've missed.
Optimistic UI Updates
Optimistic updates improve user experience by updating the UI before the server confirms the action:
- When a user sends a message, it's immediately displayed in the chat log.
- If there's an error saving the message to the server, the user is notified, and the message is removed or marked as unsent.
- This approach makes the app feel faster and more responsive.
Check it out here.