We will use socketio for real-time messaging
First install our dependency for this application
pip install flask
pip install flask-socketio
How it will work.
Every user will get an unique key.
If the the other user submit the other users key that will send the message. its like sending message to unique username
Generate Unique Key for every user
import string
import random
def generate_key():
key_length = 4
characters = string.digits
return ''.join(random.choice(characters) for _ in range(key_length))
generated_key=generate_key()
print(generated_key)
Its a 4 digit key for testing purpose. In real application must use long key with other randomness to make sure two key will not be same. Instead of key we can use unique user name. Thas another topic . For simplicity we will use this 4 digit key. Uptate it later on your necessary.
Our application structure….
step by step Explanation
when the user load the page on browser they will go to this page
@app.route('/') def index(): return render_template('index.html')
After loading the page they will connect with the socketio they will get an uniuqe key
and this key will send to the user by emiting the key to the client
also save the key in the python dictionary with the socketio sid to handle users connection activity later
When the user connected with socketio
@socketio.on('connect') def on_connect(): print('User connected') key = generate_key() active_connections[key] = request.sid emit('key_assigned', {'key': key})
When the user disconnected from socketio
If the user diconnected we will remove the user from the python dictionary.( its like active user management)
@socketio.on('disconnect') def on_disconnect(): print('User disconnected') for key, sid in active_connections.items(): if sid == request.sid: del active_connections[key] break
When the user will send message to specific user.( the logic handles on serverside socketio)
@socketio.on('send_message') def send_message(data): key = data['key'] message = data['message'] if key in active_connections: recipient_sid = active_connections[key] emit('receive_message', {'message': message}, to=recipient_sid) else: emit('receive_message', {'message': 'Does not Match'}, to=request.sid)
The Complete Server Side code
from flask import Flask, render_template,request
from flask_socketio import SocketIO, emit
import random
import string
app = Flask(__name__)
socketio = SocketIO(app)
active_connections = {}
def generate_key():
key_length = 4
characters = string.digits
return ''.join(random.choice(characters) for _ in range(key_length))
@app.route('/')
def index():
return render_template('index.html')
@socketio.on('connect')
def on_connect():
print('User connected')
key = generate_key()
active_connections[key] = request.sid
emit('key_assigned', {'key': key})
@socketio.on('disconnect')
def on_disconnect():
print('User disconnected')
for key, sid in active_connections.items():
if sid == request.sid:
del active_connections[key]
break
@socketio.on('send_message')
def send_message(data):
key = data['key']
message = data['message']
if key in active_connections:
recipient_sid = active_connections[key]
emit('receive_message', {'message': message}, to=recipient_sid)
else:
emit('receive_message', {'message': 'Does not Match'}, to=request.sid)
if __name__ == '__main__':
socketio.run(app, debug=True)
the client side code( the code we will send to browser when load the landing page index.html)
Step by step guide
First add the scoketio client side library
Add html content to show the message and users key
<!DOCTYPE html> <html> <head> </head> <body> <h1>Python Scoketio Chat Prototype</h1> <!--User unique key will be shows here --> <p>Your Unique Key: <span id="uniqueKey"></span></p> <!--This is where user will enter the friends key to send message to friend --> <input type="text" id="friendKey" placeholder="Enter Friend's Key"><br> <button onclick="startChat()">Start Chat</button><br> <!-- This is where the send and received message will shown <div id="chat"></div> <!-- This is where user will write the message <div> <input type="text" id="messageInput" placeholder="Enter your message"> <button onclick="sendMessage()">Send</button> </div> <script> </script> </body> </html>
The logical part JavaScript
connect to socket io
const socket = io(); socket.on('key_assigned', (data) => { const uniqueKeySpan = document.getElementById('uniqueKey'); uniqueKeySpan.textContent = data.key; });
When key sent by server this code will extract the key from data and place it to the html with the id name ‘uniquekey’
Initiate Chat
function startChat() { friendKey = document.getElementById('friendKey').value; const message = "Hello, let's chat!"; socket.emit('send_message', { key: friendKey, message: message }); }
this function will get key which user enter to start chat and send it to the another if that user is active
when the pervious user send the message other user will get it from client side with this code
socket.on('receive_message', (data) => { const chatDiv = document.getElementById('chat'); const messageDiv = document.createElement('div'); messageDiv.textContent = `Friend: ${data.message}`; chatDiv.appendChild(messageDiv); });
This will recieve the message from server and set it to the html chat div .
Start continuous chat
if the user initiate chat . user can send continuous chat as long as the receiver is active
as friend key already stored when the initiate the chat. so user do not have to add the key every time when send message
function sendMessage() { const message = document.getElementById('messageInput').value; if (friendKey && message) { socket.emit('send_message', { key: friendKey, message: message }); const chatDiv = document.getElementById('chat'); const messageDiv = document.createElement('div'); messageDiv.textContent = `You: ${message}`; chatDiv.appendChild(messageDiv); } }
The complete code JavaScript code for client side
<script> const socket = io(); // Store the friend's key for sending messages let friendKey = ''; // Listen for the 'key_assigned' event to display the assigned key socket.on('key_assigned', (data) => { const uniqueKeySpan = document.getElementById('uniqueKey'); uniqueKeySpan.textContent = data.key; console.log(data.key); }); function startChat() { friendKey = document.getElementById('friendKey').value; const message = "Hello, let's chat!"; socket.emit('send_message', { key: friendKey, message: message }); } function sendMessage() { const message = document.getElementById('messageInput').value; if (friendKey && message) { socket.emit('send_message', { key: friendKey, message: message }); const chatDiv = document.getElementById('chat'); const messageDiv = document.createElement('div'); messageDiv.textContent = `You: ${message}`; chatDiv.appendChild(messageDiv); } } socket.on('receive_message', (data) => { const chatDiv = document.getElementById('chat'); const messageDiv = document.createElement('div'); messageDiv.textContent = `Friend: ${data.message}`; chatDiv.appendChild(messageDiv); }); </script>
The complete client side code (index.html)
<!DOCTYPE html>
<html>
<head>
<title>Private Chat Prototype With Socketio and Flask</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script>
</head>
<body>
<h1>Private Chat Prototype With socketio and flask</h1>
<p>Your Unique Key: <span id="uniqueKey"></span></p>
<input type="text" id="friendKey" placeholder="Enter Friend's Key"><br>
<button onclick="startChat()">Start Chat</button><br>
<div id="chat"></div>
<div>
<input type="text" id="messageInput" placeholder="Enter your message">
<button onclick="sendMessage()">Send</button>
</div>
<script>
const socket = io();
// Store the friend's key for sending messages
let friendKey = '';
// Listen for the 'key_assigned' event to display the assigned key
socket.on('key_assigned', (data) => {
const uniqueKeySpan = document.getElementById('uniqueKey');
uniqueKeySpan.textContent = data.key;
console.log(data.key);
});
function startChat() {
friendKey = document.getElementById('friendKey').value;
const message = "Hello, let's chat!";
socket.emit('send_message', { key: friendKey, message: message });
}
function sendMessage() {
const message = document.getElementById('messageInput').value;
if (friendKey && message) {
socket.emit('send_message', { key: friendKey, message: message });
const chatDiv = document.getElementById('chat');
const messageDiv = document.createElement('div');
messageDiv.textContent = `You: ${message}`;
chatDiv.appendChild(messageDiv);
}
}
socket.on('receive_message', (data) => {
const chatDiv = document.getElementById('chat');
const messageDiv = document.createElement('div');
messageDiv.textContent = `Friend: ${data.message}`;
chatDiv.appendChild(messageDiv);
});
</script>
</body>
</html>
Structure
├── app.py
└── templates
└── index.html
How you will test. it?
First run the code. and open the localhost link http://127.0.0.1:5000/ in the browser. Another one in in new incognito mode
So it will act like two unique user for your testing. Then Enter the other users unique key ( which works like unique username here) Then send message . Thats all. customize the code your necessary. Happy coding!
You can also get this project code from github
https://github.com/01one/flask-socketio-chat-application