Using Websockets with Python
By: Anand Tripathi
Tags: Flask, JavaScript, Python, Websocket, Socketio

WebSocket

Websocket is a communications protocol, providing full-duplex bi-directional communication over a single TCP connection.

To understand Websockets, first, we have to have a clear understanding of HTTP protocol cause both go hand in hand.

HTTP protocol life cycle

HTTP is a protocol which allows the fetching of resources, such as HTML documents. It is the foundation of any data exchange on the Web and it is a client-server protocol, which means requests are initiated by the recipient, usually the Web browser.

HyperText Transfer Protocol is an application layer is a stateless application-level protocol where generally client requests information with headers using actions like GET, POST, PUT … and server sends the response back to the client and the connection is closed.

For every communication, HTTP protocol will open a connection, data exchange then the connection is closed.

If the requirement is to fetch the data continuously from the server. For example fetch the realtime data for cryptocurrency exchange, gaming application or for a chat application. Then there will be multiple HTTP calls to the server.

SAVE the SERVER

Photo by Vilmar Simion on Unsplash

How’s the Websocket is different from traditional HTTP protocols. Websockets uses bi-directional communication and the connection will not break until the client or server decides to terminate the connection.

Credit goes to https://blog.stanko.io/do-you-really-need-websockets-343aed40aa9b

The life cycle of Websockets

Handshake

Websocket is also an application layer protocol and it is an HTTP upgrade that uses the same TCP connection over ws://

In simple terms client asks for the server that, can we make a WebSocket connection and in reply server will say, yeah buddy let’s upgrade the connection to WS

This is called the handshake and the connection is established between client and server.

Open and Persistent Connection

Once the connection is established communication happens in terms of bi-directional message communication.

Connection Closed

Once the connection is established its stays forever until the client or server wants to terminate the connection.

Enough of the theory, let’s dive into the implementation. So to have a WebSocket connection we first need to have a client and a server. For the implementation, we are using Python’s Flask Server that is a microframework.

tenor

We will be using Socket.io for the client socket library and Flask-SocketiIO for the server WebSocket library for our example.

Flask-SocketIO

Lets first install all our dependencies to run the project like flask-socketio or may be flask if that is not installed yet. As the WebSocket can connect to n number of clients so flask has to use some asynchronous libraries like Eventlet or Gevent. So in our case, we are installing Eventlet.

To run the project with Eventlet thread library let’s install Gunicorn web server or maybe you can use UWsgi server.

Now we just have to set up the flask project and initialize the flask-socketio and for more information please visit the official docs of flask-socketio

Now by default, the server is running on 5000 port with WebSocket. Now we just need to connect from the client to the server. Let’s make the connection using Socket.io

Socket.io

To install socket.io either you can use CDN for it or if you are using npm then just fire

And to simplify our solution we are using CDN link

So above code will connect to localhost server on port 5000 on which we have already started our flask server with WebSocket. Now our client is connected with our server and you can check that in the web console with the statement as socket connected

And to check whether the client is connected to the server or not just add the below code.

@socket_io.on('connect')

def test_connect():

print("socket connected")

Now as the client and server are connected then there’s an HTTP upgrade happened and the connection is made on ws://localhost:5000 with status code as 101(Switching Protocols). And now all the data exchange will happen on the same network call only. You can test that our in the network tab there is a header called WS in chrome.

So let’s send some data from client to the server over the same network without creating any new network call. To send a message from client to server you can either use send or emit method.

socket.emit('message', { 'hello': 'world' });

You can even send the data to the server with a custom event just change the first parameter to anything else. But just be sure that there should be a receiver configured on the server that is listening to that event.

With Flask-SocketIO the server needs to register handlers for these events, similarly to how routes are handled by view functions.

The following example creates a server-side event handler for an unnamed event:

@socketio.on('message')

def handle_message(message):

print('received message: ' + message)

The above example uses string messages. Another type of unnamed events use JSON data:

@socketio.on('json')

def handle_json(json):

print('received json: ' + str(json))

SocketIO event handlers defined as shown in the previous section can send reply messages to the connected client using the send() and emit() functions.

The following examples bounce received events back to the client that sent them:

from flask_socketio import send, emit @socketio.on('message')

def handle_message(message):

send(message) @socketio.on('json')

def handle_json(json):

send(json, json=True) @socketio.on('my event')

def handle_my_custom_event(json):

emit('my response', json)

Note how send() and emit() are used for unnamed and named events respectively.

Broadcasting

Another very useful feature of SocketIO is the broadcasting of messages. Flask-SocketIO supports this feature with the broadcast=True optional argument to send() and emit() :

@socketio.on('my event')

def handle_my_custom_event(data):

emit('my response', data, broadcast=True)

When a message is sent with the broadcast option enabled, all clients connected to the namespace receive it, including the sender.

And to handle the messages coming from the server, we have to register a new handler for the given event on the client-side, so that client can get the message from the server.

socket.on('my event', (data) => {

console.log(data); // this will log the output that server has send to the client

});

Where to use Websockets instead of traditional HTTP calls

Realtime applications like bitcoin exchange. Just check out the link and open the chrome dev-tools network tab you can see massive to and fro of the data happening.

2. Chat application. You can check out Socket.io chat application that uses the WebSocket concept. Please check out the link for chat application demo.

Conclusion

Websockets are very easy, lightweight and super interesting when you see a lot of data is flowing to and fro in a single call, without bombarding the server with too much of network calls.

This was just my understanding of Websocket. I hope, it has helped you. If you want to discuss with me about anything or anything related to tech, you can contact me here or on Linkedin.