Implement a WebSocket Using Flask and Socket-IO(Python)

Learn how to compose the client-server interface utilizing Websocket technology with Flask and Socket-IO modules available in python

Narendra Harny
Aug 17, 2020 · 6 min read
WebSocket

ebSocket is a communication protocol for the client-server model.
So for understanding WebSocket, It is batter to compare the WebSocket specialty over HTTPS.
There are a few advantages of WebSocket over HTTPS that is what the specialty of WebSocket.
So If we have to decide that we should choose the WebSocket for our applications then we can analyze the requirements as per the below-written features of WebSocket.

HTTP carries extra overheard in individual request and response, WebSocket carries the overhead data while placing connection then it carries less or balanced data within individual request-response.

Difference HTTP vs WebSocket

Note: For full-duplex Bi-directional client-server communication the WebSocket is the best choice.

The WebSocket’s can be implemented with all server-side technologies, I am using Flask and Socket-IO modules from Python.
Please understand the steps below to implement the WebSocket using Flask and Socket-IO

Step1: Creating a project and creating requirements.txt

  • First of all, will start by setting up the virtual environment for our sample project.
  1. Create a project folder.
  2. Create a requirments.txt file into the project folder.
  3. Add below code into requirments.txt.
Flask==1.0.2
Flask-Login==0.4.1
Flask-Session==0.3.1
Flask_SocketIO
itsdangerous==1.1.0
Jinja2==2.10
MarkupSafe==1.1.0
python-engineio
python-socketio
six==1.11.0
Werkzeug==0.14.1

Note: the above dependency is required for implementing a web socket so we will install all for creating the virtual environment.

Step2: Creating a virtual environment and install all required modules from python.

  • Now create a virtual environment “VENV” for the project.
create a virtual environment
  • Go to project root folder and open terminal/cmd and execute the below commands

$ virtualenv <envname>:

envname” can be anything I have used “websocketenv”

  • Activate the virtual env now(Execute the activate.bat file present location)

$ {Project Root path}/websocketenv/Scripts/activate.bat

  • Now install the requirements.txt using the command

$ pip install requirements.txt

The current project structure looks like this. for me.

Current project structure

Step3: We will design a simple program for understanding the functionality of a WebSocket.

  • Create a Python file named app.py in the project root folder.
  • Add the below code into the app.py

Note: First We are creating a client GUI web page for implementing the WebSocket basic feature of a running WebSocket.

app.py

from flask import Flask, render_template
from flask_socketio import SocketIO
async_mode = None
app = Flask(__name__)
socket_ = SocketIO(app, async_mode=async_mode)
@app.route('/')
def index():
return render_template('index.html',
sync_mode=socket_.async_mode)


if __name__ == '__main__':
socket_.run(app, debug=True)
  • Now create the templates directory into the project root folder and create one index.html file in the templates directory.
  • Add the below code into index.html

index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebSocket</title>
</head>
<body>
<h1>This is webSocket client</h1>
</body>
</html>

Now we can test the WebSocket by running “app.py”

The expected console output will be after running app.py

WebSocket console output

Now run the URL: http://localhost:5000/ into a web browser and you will see the message “This is WebSocket Client” on the web page.

**127.0.0.1 — — [2020–08–17 10:09:07] “GET / HTTP/1.1” 200 260 0.004024**

If the WebSocket connection is established then the above request log will be added in the console logs whenever the web page will get refreshed.

Flask, render_template
flask_socketio , SocketIO

we have used the following modules for implementing the basic socket but it is not showcasing anything like how socket works so, let’s extend the feature and implement the sending message and receiving from one client to another.

Final Step: We will implement a message passing from one client to another client in this step.

The current project structure is like this:

Current Project structure

The final code for app.py and index.html

app.py

from flask import Flask, render_template, session, copy_current_request_context
from flask_socketio import SocketIO, emit, disconnect
from threading import Lock


async_mode = None
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socket_ = SocketIO(app, async_mode=async_mode)
thread = None
thread_lock = Lock()


@app.route('/')
def index():
return render_template('index.html', async_mode=socket_.async_mode)


@socket_.on('my_event', namespace='/test')
def test_message(message):
session['receive_count'] = session.get('receive_count', 0) + 1
emit('my_response',
{'data': message['data'], 'count': session['receive_count']})


@socket_.on('my_broadcast_event', namespace='/test')
def test_broadcast_message(message):
session['receive_count'] = session.get('receive_count', 0) + 1
emit('my_response',
{'data': message['data'], 'count': session['receive_count']},
broadcast=True)


@socket_.on('disconnect_request', namespace='/test')
def disconnect_request():
@copy_current_request_context
def can_disconnect():
disconnect()

session['receive_count'] = session.get('receive_count', 0) + 1
emit('my_response',
{'data': 'Disconnected!', 'count': session['receive_count']},
callback=can_disconnect)


if __name__ == '__main__':
socket_.run(app, debug=True)

index.html

<!DOCTYPE HTML>
<html>
<head>
<title>Socket-Test</title>
<script src="//code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"></script>
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {

namespace = '/test';
var socket = io(namespace);

socket.on('connect', function() {
socket.emit('my_event', {data: 'connected to the SocketServer...'});
});

socket.on('my_response', function(msg, cb) {
$('#log').append('<br>' + $('<div/>').text('logs #' + msg.count + ': ' + msg.data).html());
if (cb)
cb();
});
$('form#emit').submit(function(event) {
socket.emit('my_event', {data: $('#emit_data').val()});
return false;
});
$('form#broadcast').submit(function(event) {
socket.emit('my_broadcast_event', {data: $('#broadcast_data').val()});
return false;
});
$('form#disconnect').submit(function(event) {
socket.emit('disconnect_request');
return false;
});
});
</script>
</head>
<body style="background-color:white;">

<h1 style="background-color:white;">Socket</h1>
<form id="emit" method="POST" action='#'>
<input type="text" name="emit_data" id="emit_data" placeholder="Message">
<input type="submit" value="Send Message">
</form>
<form id="broadcast" method="POST" action='#'>
<input type="text" name="broadcast_data" id="broadcast_data" placeholder="Message">
<input type="submit" value="Send Broadcast Message">
</form>

<form id="disconnect" method="POST" action="#">
<input type="submit" value="Disconnect Server">
</form>
<h2 style="background-color:white;">Logs</h2>
<div id="log" ></div>
</body>
</html>

After adding the final code please start the WebSocket server by running app.py and now again we can check the output in the web browser.

Output web page socket server
  • Here we have implemented two kinds of message one is “Send Message” that’s is a normal ping msg and Send Broadcast Message which is sending or broadcasting the data over a socket connection.
  • We have a couple of options to check the functionality but if we run socket on localhost then it's difficult to observe the feature.

Make your localhost accessible anywhere.

We can use the “NGROK” tool and we can easily make localhost servers accessible anywhere.

One the localhost is set up according to the above link, you can use the generated HTTP or HTTPs URLs instead of the localhost and You can test a Socket server like a live hosted server and use it as a simple chat broadcast server.

Can open the link into your phone and see the message sharing in between. Or use another computer and test exchanging messages.

Please explore the code one by one and here I have given some explanations about few must-know things from source code.

async_mode = None
app = Flask(__name__)
socket_ = SocketIO(app, async_mode=async_mode)

we were given the Flask app instance (standard initialization)
we were not given the app, but we were given a message_queue (standard initialization for the auxiliary process), will call init_app from an app factory function.

@app.route('/')

A decorator that is used to register a view function for a given URL rule.

@socketio.on('my event', namespace='/chat')

A Decorator to register a SocketIO event handler. This decorator must be applied to SocketIO event handlers.

This small application can be extended for any features please do have use of it freely.

Thanks, Programmers

Happy Coding!

The Startup

Get smarter at building your thing. Join The Startup’s +785K followers.

Sign up for Top 10 Stories

By The Startup

Get smarter at building your thing. Subscribe to receive The Startup's top 10 most read stories — delivered straight into your inbox, once a week. Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Narendra Harny

Written by

Software Developer with Stack: Android, JAVA, Python, DevOps | Writer | Technical Trainer | Technologies Enthusiast, Motivational Speaker, Learner Forever

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +785K followers.

Narendra Harny

Written by

Software Developer with Stack: Android, JAVA, Python, DevOps | Writer | Technical Trainer | Technologies Enthusiast, Motivational Speaker, Learner Forever

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +785K followers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store