The website I am building has a real-time messaging component. The backend is built with Flask and I have integrated Flask-SocketIO to handle Websocket connections when users are on the messaging page.
My current infrastructure is pretty simple. Flask handles both HTTP requests and Websocket events. When users land on the Messages page, the client sends a
GET /message_history request and then opens a socket connection.
When Alice sends a message to Bob, the server handles the event, checks that Alice is logged in and is allowed to talk to Bob, then stores the message in the database and finally emits the message back to both Alice and Bob, whose clients are listening for events from the server.
This works fine in development but for production I need to make changes.
Primarily, this won't work under a load-balancer. As per the Flask-SocketIO docs:
There are two requirements to use multiple Flask-SocketIO workers:
The load balancer must be configured to forward all HTTP requests from a given client always to the same worker. This is sometimes referenced as “sticky sessions”.
Since each of the servers owns only a subset of the client connections, a message queue such as Redis or RabbitMQ is used by the servers to coordinate complex operations such as broadcasting and rooms.
However, I don't quite understand how to implement Redis or RabbitMQ as part of my current event handlers, since the clients will not be connecting to Redis/RabbitMQ directly. The Flask server will always need to be the middleman since it needs to perform checks and store the messages in the database.
Take a look at this answer on SO:
Redis pub/sub is great in case all clients have direct access to redis. If you have multiple node servers, one can push a message to the others.
But if you also have clients in the browser, you need something else to push data from a server to a client, and in this case, socket.io is great.
Now, if you use socket.io with the Redis store, socket.io will use Redis pub/sub under the hood to propagate messages between servers, and servers will propagate messages to clients.
I followed the docs: I have Redis running locally, I have installed the dependecies and monkey-patched eventlet. I ran everything and it works... ? I see that Redis is receiving "SUBSCRIBE" and "PUBLISH" events...
Do I still need my PSQL database? Can I use the Redis store to fetch historic messages? What happens if the Redis instance dies?
If I run this under a load-balancer, and have configured sticky sessions, does Redis (or Flask?) automagically know how to distribute the messages to the correct nodes?