How to use Socket.IO with Flask/Heroku

by Rohan Juneja

Posted on May 30, 2020 7:00 PM

Socket.IO is a great libary to use in order to communicate between a server and client securely and quickly. In this blog I will teach you how to use this technology with Flask and Heroku in a simple Chatting app.

If you haven't already, check out my previous post about Heroku/Flask to set up a basic Heroku/Flask Server

We need to install these packages and add them to requirements.txt

pip install Flask-SocketIO eventlet gevent-websocket

In addition, we need to add this line to Procfile to start a Socket.IO Server

web: gunicorn --worker-class eventlet -w 1 app:app

Now, we can use Socket.IO. For this tutorial I will create a simple messaging app

On index.html, you can insert this code which will create a basic textbox and chat area

<div id="chat"></div>
<input type="text" id="chat-input"> <button onclick="sendMessage()>Send</button>

Socket.IO Basic Website

Now, our button has an onclick of sendMessage(), but we obviously need to create that function. For now, let us just print the message to the console

<script>
    function sendMessage () {
        console.log(document.getElementById("chat-input").value)
    }
</script>

Now, you can see that when you send a message, it shows up in the console.

Javascript Console

Now, we need to import Socket.IO and intialize the connection on our client

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"></script>
<script>
    var socket = io()
    function sendMessage () {
        console.log(document.getElementById("chat-input").value)
    }
</script>

The next thing we want to do is to send a message to the server everytime a message is sent.

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"></script>
<script>
    var socket = io()
    function sendMessage () {
        console.log(document.getElementById("chat-input").value)
        socket.emit(message,document.getElementById("chat-input").value)
    }
</script>

Here we emit a message with the title "message" and data containing what the message is. Now, let us go back to our server in app.py so we can respond to this Socket.IO message. We need to import Socket.IO and run the app with Socket.IO as so:

from flask import Flask, render_template, make_response, redirect
from flask_socketio import SocketIO, send, emit

app = Flask(__name__)
socketio = SocketIO(app)

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

@socketio.on("message")
def handleMessage(data):
    emit("new_message", data, broadcast=True)

if __name__ == "__main__":
    socketio.run(app, debug=True, port=5004)

Here, we say if a Socket.IO message is sent with the title "message", we will emit a Socket.IO message to the clients with a title "new_message" containing the data of the message. Additionally, "broadcast=True" broadcasts the message to all clients.

Now, back on index.html, we need to handle the "new_message" message sent by the server inside the script tag.

socket.on("new_message", (data) => {
    document.getElementById("chat").innerHTML += "<br>" + data
})

This code creates a newline and then adds any message sent to the message div. Now you can push your code to GitHub and test out your app on Heroku!

Final Product

You can see my code on github and try an interactive demo at this website.