Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I send a message from a flask route to a socket using flask-socketio

I have the following scenario I would like to implement:

  • User surfs to our website
  • User enters a bitcoin address.
  • A websocket is created to the server, passing the address.
  • The server registers a callback with Blocktrail
  • When the callback is triggered (a payment was seen by Blocktrail) we send a message back to the browser.
  • The page the user is browsing is updated to show the message recieved

I'm using webhooks from the Blocktrail API to "listen" to an event, being the reception of coins on an address.

Now, when the event happens, the API does a POST to my URL. This should send a message to the browser that is connected to my server with socket.io (such as 'payment seen on blockchain')

So the question is,

How can I send a message from a route to a socket using flask-socketio

Pseudo code:

@app.route('/callback/<address>')
def callback(id):
    socketio.send('payment seen on blockchain')

@socketio.on('address',address)
def socketlisten(address):
    registerCallback(address)
like image 453
Dennis Decoene Avatar asked Oct 08 '15 07:10

Dennis Decoene


People also ask

Does Flask support WebSockets?

Flask-SocketIO is a Flask extension that relies upon eventlet or gevent to create server-side WebSockets connections. websocket-client provides low level APIs for WebSockets and works with both Python 2 and 3.

How do you transfer data using a Flask?

Flask sends form data to template Flask to send form data to the template we have seen that http method can be specified in the URL rule. Form data received by the trigger function can be collected in the form of a dictionary object and forwarded to the template to render it on the corresponding web page.


1 Answers

I'm going to describe how to solve this using Flask-SocketIO beta version 1.0b1. You can also do this with the 0.6 release, but it is a bit more complicated, the 1.0 release makes addressing individual clients easier.

Each client of a socket connection gets assigned a session id that uniquely identifies it, the so called sid. Within a socket function handler, you can access it as request.sid. Also, upon connection, each client is assigned to a private room, named with the session id.

I assume the metadata that you receive with the callback allows you to identify the user. What you need is to obtain the sid of that user. Once you have it, you can send your alert to the corresponding room.

Example (with some hand-waving regarding how you attach a sid to an address):

@app.route('/callback/<address>')
def callback(address):
    sid = get_sid_from_address(address)
    socketio.send('payment seen on blockchain', room=sid)

@socketio.on('address')
def socketlisten(address):
    associate_address_with_sid(address, request.sid)
like image 171
Miguel Avatar answered Sep 25 '22 04:09

Miguel