barha
barha

Reputation: 689

Websocket (socket.io) proxy with python flask and nodejs

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

Answers (1)

Sovanna
Sovanna

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

Related Questions