Creating Real-Time Streaming Apps with WebSockets in Python
Written on
Chapter 1: Introduction to Real-Time Applications
Developing scalable real-time data streaming solutions can be a complex endeavor. Particularly, applications that facilitate connections between client and server can automatically notify clients without requiring them to constantly check in with the server.
This article will illustrate how to create interactive real-time applications using WebSockets in Python.
For instance, when visiting the Yahoo Finance webpage, users can observe that stock prices refresh automatically without any manual page reload. Similarly, chatbot servers can send notifications to clients without a refresh, and trading or gaming applications can push updates to clients as data becomes available. Many organizations utilize JavaScript for client applications while employing Python for server-side programming.
This guide will explore how to harness WebSockets in Python for real-time streaming applications.
We leverage WebSockets to develop interactive data streaming applications. A widely accepted method for creating fast real-time applications is through the WebSockets communication protocol. Below, I provide a working example that illustrates how WebSockets function in practice.
Section 1.1: Understanding WebSockets
WebSocket is a communication protocol that operates over a TCP/IP socket connection, enabling client-server interactions. Key features include:
- Bidirectional Communication: Both clients and servers can send and receive messages.
- Stateful Connection: The connection remains active until either party closes it.
- Real-Time Notifications: Ideal for scenarios where server applications need to notify clients of real-time events.
- Cross-Language Compatibility: Clients can be browser applications, with support from most modern browsers, including Chrome, Internet Explorer, and Firefox.
- Multiple Connections: A single server can handle multiple client connections and broadcast messages to all.
Section 1.2: Mechanism of WebSockets
A WebSocket server listens on a specified port, e.g., ws://localhost:6565. Clients initiate a connection through a handshake, which the server can validate to either proceed or terminate the connection. Once connected, both parties can send and receive messages over the WebSocket protocol, allowing for faster communication with reduced overhead compared to traditional HTTP polling. The connection persists until one side decides to end it. Furthermore, scalability can be achieved by introducing a load balancer in front of the WebSocket servers.
Chapter 2: Implementing a WebSocket Application
To get started, you will need to install the following dependencies:
pip install websockets
I prefer using the websockets library for its simplicity and robustness, as it is built on asyncio, providing an elegant coroutine-based API.
Creating a WebSocket Server
Begin by creating a file named websocket_server.py and insert the following code:
import asyncio
import datetime
import time
import websockets
class WebSocketServer:
def __init__(self, host, port, secret):
self._secret = secret
self._server = websockets.serve(self._start, host, port)
def start(self):
asyncio.get_event_loop().run_until_complete(self._server)
asyncio.get_event_loop().run_forever()
async def _start(self, websocket, path):
print(f"Connected from path ={path}")
while True:
secret = await websocket.recv()
if secret == self._secret:
time.sleep(1)
msg = f"Sending message {datetime.datetime.now()}"
await websocket.send(msg)
print(msg)
if __name__ == "__main__":
server = WebSocketServer("127.0.0.1", 6969, "fintechexplained")
server.start()
This code sets up a WebSocketServer class that wraps around the websockets library. It listens for incoming client connections and, upon receiving a specific message, responds with a timestamped message.
Creating a WebSocket Client
Next, create a file called websocket_client.py and add the following code:
import asyncio
import websockets
class WebSocketClient:
def __init__(self, host, port, secret):
self._secret = secret
self._host = host
self._port = port
def start(self):
asyncio.get_event_loop().run_until_complete(self._start_receiving())
async def _start_receiving(self):
url = f'ws://{self._host}:{self._port}/websocket-blog'
try:
async with websockets.connect(url) as websocket:
await websocket.send(self._secret)
while True:
await websocket.send(self._secret)
response = await websocket.recv()
print(f'Received Message: {response}')
except websockets.ConnectionClosed as ex:
print(ex)
raise
if __name__ == "__main__":
client = WebSocketClient("127.0.0.1", 6969, "fintechexplained")
client.start()
This WebSocketClient class connects to the server and continuously sends and receives messages.
Running the WebSocket Server and Client
- Execute websocket_server.py in one terminal.
- Execute websocket_client.py in another terminal.
Once the client connects and sends its initial message, the server will start sending messages in response.
Summary of WebSocket Architecture
Utilizing multiple WebSocket servers and clients within isolated containers can enhance efficiency. Containers provide numerous benefits, such as faster application deployment, scalability, and improved management.
For further insights into containers and their advantages, I recommend exploring additional resources.
Chapter 3: Video Resources
To enhance your understanding of building real-time applications, consider watching the following videos:
This video, titled "Build Streaming Data Applications in Minutes Using SwimOS and Nstream," provides an overview of rapid application development in streaming data.
In this video, "Build On AWS - Building a Live Streaming App in 25 Minutes," you will learn to create a live streaming application using AWS tools.
This article has demonstrated how to develop real-time interactive applications using WebSockets in Python.