Skip to content

WebNinjaDeveloper.com

Programming Tutorials




Menu
  • Home
  • Youtube Channel
  • Official Blog
  • Nearby Places Finder
  • Direction Route Finder
  • Distance & Time Calculator
Menu

Build a Flask-Socket.io Chat App With Image Sending Using HTML5 Forms in Browser Using Javascript

Posted on January 7, 2023

 

 

Welcome folks today in this blog post we will be using the flask-socket.io library to create a chat app with image sending support in browser using html5 forms in browser using javascript. All the full source code of the application is shown below.

 

 

Get Started

 

 

In order to get started you need to install the below libraries using the pip command as shown below

 

 

pip install –upgrade Flask-SocketIO==5.2.0

 

pip install –upgrade python-engineio==4.3.3

 

pip install –upgrade python-socketio==5.7.1

 

pip install –upgrade simple-websocket==0.7.0

 

 

And now you need to create the app.py file and copy paste the following code

 

 

app.py

 

 

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from flask import Flask, render_template
from flask_socketio import SocketIO, send, emit
 
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
 
@app.route('/')
def index():
    return render_template('index.html')
 
if __name__ == '__main__':
    app.debug = True
    socketio.run(app)

 

 

As you can see in the above code we are importing all the flask libraries and then we are starting the flask app at the port number 5000.And also we are setting the debug option to true to see the log messages. And also we are setting the secret key of the flask app and then we are wrapping the flask app inside the SocketIO library. And also we are making a simple get route at the / endpoint. Whenever the user opens the homepage they will see the index.html template file

 

Now you will need to create the templates folder and inside it you need to create the index.html file and copy paste the following code

 

 

templates/index.html

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html>
  <head>
    <title>Chat</title>
    <script src="https:///cdnjs.cloudflare.com/ajax/libs/socket.io/4.2.0/socket.io.js"></script>
  </head>
  <body>
    <form id="form">
      <input id="input" type="text" placeholder="Enter message here">
      <input id="image" type="file" accept="image/*">
      <button type="submit">Send</button>
    </form>
    <ul id="messages"></ul>
  </body>
</html>

 

 

As you can see we are including the cdn for the socket.io library at the client side inside the html and then we have the simple html form where we have the input field where we allow the user to enter the chat message and then we have the image upload field where we allow the user to select the images and then we have the button to send the message. And then we have the ul element where we are showing all the messages.

 

Now if you run the flask app by executing the below command

 

 

python app.py

 

 

The app will start on http://localhost:5000. And now if you open it you will see the html form as shown below

 

 

 

 

And now we will be writing the javascript code inside the index.html file to add the functionality to the chat app. Here we will be communicating with the backend at the flask and socket.io

 

Just make a script.js file and include the below javascript code

 

 

script.js

 

 

JavaScript
1
2
3
4
var socket = io();
var form = document.getElementById('form');
var input = document.getElementById('input');
var imageInput = document.getElementById('image');

 

 

As you can see we are getting the references of all the DOM elements which are there inside the html file. And also we are starting the socket.io server at the client side by invoking a new reference of the io() method.

 

 

Sending Text Messages From Client to Backend

 

 

Now guys we will be taking the message which is submitted by the user at the input field and when the button is pressed this form submit event will be triggered and inside it we will be emitting a event to the socket.io server as shown below

 

 

JavaScript
1
2
3
4
5
6
form.addEventListener('submit', function(event) {
        event.preventDefault();
        var message = input.value;
        socket.emit('message', message);
        input.value = '';
      });

 

 

As you can see we are passing the actual message which is typed by the user inside the input field and then we are using the emit() method to send the event to the socket.io server.

 

 

Receiving Message on Socket.io (Backend Side)

 

 

Now guys we will be catching the messages or events passed at the client side in the backend side app.py (flask) as shown below

 

 

1
2
3
4
@socketio.on('message')
def handle_message(message):
    print('received message: ' + message)
    send(message, broadcast=True)

 

 

As you can see we are wrapping the request inside the @socketio.on('message') decorator and inside it we are getting the message passed from the client side and inside we are broadcasting this message to all the clients connected using the send() method and inside it we are passing the broadcast option to True

 

 

Displaying Chat Text Messages

 

 

Now guys we need to again add some javascript code inside the script.js to catch the messages send by the backend to all the clients whenever some client sends out a message. We need to update the screen with new messages as shown below

 

 

JavaScript
1
2
3
4
5
socket.on('message', function(message) {
        var li = document.createElement('li');
        li.textContent = message;
        document.getElementById('messages').prepend(li)
      });

 

 

As you can see we are using the on() method to receive the message or event and inside it we are creating a new li tag and inside it we are manipulating the text content of the message and displaying it on the screen using the appendChild() method.

 

 

 

 

Image Sending Using Socket.io

 

 

Now we need to repeat the same task for the image sending as well in between multiple clients using socket.io and javascript. First of all go to script.js and add some code to it as shown below

 

 

JavaScript
1
2
3
4
5
6
7
8
imageInput.addEventListener('change', function(event) {
        var file = imageInput.files[0];
        var reader = new FileReader();
        reader.addEventListener('load', function() {
          socket.emit('image', reader.result);
        });
        reader.readAsDataURL(file);
      });

 

 

As you can see we are selecting the image which is selected by the user using the input field by using FileReader() class and after reading the content of the image file as base64 code we are passing that code to the backend using the emit() method at the backend side to the socket.io server.

 

 

Receiving Base64 Code of Image at Backend

 

 

Now guys we will be receiving the base64 code of the image at the backend which is sent by the client side everytime someone tries to upload the image Now copy paste the below code inside the app.py file

 

 

Python
1
2
3
4
@socketio.on('image')
def handle_image(image_data):
    print('received image: ' + image_data)
    emit('image', image_data, broadcast=True)

 

 

As you can see this time we are using the socketio.on('image') decorator to catch the base64 code of the image and the send this code to all the connected clients using the emit() method and inside it we are passing the broadcast option to True.

 

 

Displaying Images in Browser

 

 

Now guys we will be displaying the images inside every client browser using the base64 code which is passed from backend side as shown below

 

 

JavaScript
1
2
3
4
5
6
7
8
9
socket.on('image', function(image_data) {
        var li = document.createElement('li');
        var img = document.createElement('img');
        img.src = image_data;
        img.width = 300
        img.height = 300
        li.appendChild(img)
        document.getElementById('messages').prepend(li)
      });

 

 

As you can see we are again using the on() method to catch the event or data passed from the backend side and inside it we are simply creating the dynamic image element by attaching the dynamic base64 code of the image. And then we are simply displaying the image using the appendChild() method.

 

 

 

 

Full Source Code

 

 

 

 

templates/index.html

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<!-- templates/index.html -->
 
<html>
  <head>
    <title>Chat</title>
    <script src="https:///cdnjs.cloudflare.com/ajax/libs/socket.io/4.2.0/socket.io.js"></script>
  </head>
  <body>
    <form id="form">
      <input id="input" type="text" placeholder="Enter message here">
      <input id="image" type="file" accept="image/*">
      <button type="submit">Send</button>
    </form>
    <ul id="messages"></ul>
 
    <script>
      var socket = io();
      var form = document.getElementById('form');
      var input = document.getElementById('input');
      var imageInput = document.getElementById('image');
 
      form.addEventListener('submit', function(event) {
        event.preventDefault();
        var message = input.value;
        socket.emit('message', message);
        input.value = '';
      });
 
      imageInput.addEventListener('change', function(event) {
        var file = imageInput.files[0];
        var reader = new FileReader();
        reader.addEventListener('load', function() {
          socket.emit('image', reader.result);
        });
        reader.readAsDataURL(file);
      });
 
      socket.on('message', function(message) {
        var li = document.createElement('li');
        li.textContent = message;
        document.getElementById('messages').prepend(li)
      });
 
      socket.on('image', function(image_data) {
        var li = document.createElement('li');
        var img = document.createElement('img');
        img.src = image_data;
        img.width = 300
        img.height = 300
        li.appendChild(img)
        document.getElementById('messages').prepend(li)
      });
    </script>
  </body>
</html>

 

 

app.py

 

 

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# server.py
 
from flask import Flask, render_template
from flask_socketio import SocketIO, send, emit
 
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
 
@app.route('/')
def index():
    return render_template('index.html')
 
@socketio.on('message')
def handle_message(message):
    print('received message: ' + message)
    send(message, broadcast=True)
 
@socketio.on('image')
def handle_image(image_data):
    print('received image: ' + image_data)
    emit('image', image_data, broadcast=True)
 
if __name__ == '__main__':
    app.debug = True
    socketio.run(app)

 

Recent Posts

  • Android Java Project to Capture Image From Camera & Save it inside Gallery
  • Android Java Project to Crop,Scale & Rotate Images Selected From Gallery and Save it inside SD Card
  • Android Kotlin Project to Load Image From URL into ImageView Widget
  • Android Java Project to Make HTTP Call to JSONPlaceholder API and Display Data in RecyclerView Using GSON & Volley Library
  • Android Java Project to Download Youtube Video Thumbnail From URL & Save it inside SD Card
  • Angular
  • Bunjs
  • C#
  • Deno
  • django
  • Electronjs
  • java
  • javascript
  • Koajs
  • kotlin
  • Laravel
  • meteorjs
  • Nestjs
  • Nextjs
  • Nodejs
  • PHP
  • Python
  • React
  • ReactNative
  • Svelte
  • Tutorials
  • Vuejs




©2023 WebNinjaDeveloper.com | Design: Newspaperly WordPress Theme