Reputation: 689
I have Python Flask server and NodeJS server, I am running socket.io server on NodeJS and my static app is served using python Flask server. Is it possible to connect to the socket.io server through the Flask app? I am having difficulties proxying the /socket.io endpoint in NodeJS to Flask, any hints?
I am using Socket.IO for NodeJS as server running at port 8888, python flask running at port 5000
Upvotes: 3
Views: 1577
Reputation: 78
Yes you can!
On the socket.io server, I have something like:
io.on('connection', (socket) => {
socket.emit('init', { id: socket.id, status: 'connected'});
socket.on('user connected', (data) => {
register_socket_client(redisClient, data);
});
socket.on('disconnect', () => {
unregister_socket_client(redisClient, socket.id);
});
});
server.listen(8080, '0.0.0.0', () => {
console.log('[*] Server listening on port 8080');
});
Note that I stored the socket_client in a redis instance. I let you assume how you can implement the function to save, unsave something in redis
So, in a html file render by flask, we have:
// http://localhost:8080 refer to your socket.io server
var socket = io('http://localhost:8080');
var user_connected = "{% if current_user.is_anonymous %}false{% else %}true{% endif %}" === 'true';
socket.on('init', function (data) {
if (user_connected) {
socket.emit('user connected', { user_id: xxx, socket_id: Nxxx});
socket.on('notify', function (data) {
// Do something, modify the DOM to add an alert on your app
console.log(data);
});
}
});
Do not pay attention to user_connected thing. It's just that I only need to connect socket.io only for connected user
now your static app rendered by flask should be connected with your socket.io
I also have an private endpoint (just with jwt token) on the socket.io server like this:
app.post('/notify', passport.authenticate('jwt', { session: false}), (req, res) => {
const query = req.query;
const payload = req.body;
if (query.user_id) {
// here you can retrieve the data from redis based on user_id for example
// We can assume that we have everything in a `data` variable.
io.to(data.socket_id).emit('notify', payload);
}
return res.status(200).json({'ping': 'pong'});
});
And the flask server can make a request like request.post('http://localhost:8080/?user_id=USER_ID', data={})
Upvotes: 2