Reputation: 617
I have a web application and need to continuously display the actions going on in the backend on the browser. I have been trying to use socket.io in Flask. But I need to get the data to be displayed from other Python modules in my project. So, I tried to make a socket connection between Flask and the external module from which I will be getting data to be displayed on the browser(without any delay).
@socketio.on('my event')
def server(message):
s = socket.socket()
print "Socket successfully created"
port = 12345
s.bind(('', port))
print "socket binded to %s" %(port)
s.listen(5)
print "socket is listening"
while True:
c, addr = s.accept()
print 'Got connection from', addr
print c.recv(1024)
emit('my response', {'data': c.recv(1024)})
c.close()
print c.recv(1024)
is printing data on the console. But the same data is not getting reflected on the browser. It's throwing this error -
error: [Errno 98] Address already in use
This means it's failing at emit
after print c.recv(1024)
. What could be going wrong?
My first doubt is if this kind of connection is allowed. I mean, can we have a socket connection created inside socket.io in Flask?
Else, what is the best solution to display the backend actions on the browser continuously using Flask? I also have the web application with Django. Any solution for my use case with either Flask or Django will be appreciated (preferably Django).
Upvotes: 1
Views: 2563
Reputation: 617
Using the answer given by Miguel, I could find an appropriate solution. In the external script, we need to create a SocketIO
object as follows:
socketio = SocketIO(message_queue='redis://')
Then I can use emit
to send the data to be displayed on the front end.
def fn():
socketio.emit('my response', {'data': 'ur data goes here'})
fn()
And on the frontend,
var socket = io.connect('http://' + document.domain + ':' + location.port);
socket.on('connect', function() {
socket.on('my response', function(msg) {
$('#log').append('<p>Received: ' + msg.data + '</p>');
document.getElementById('<div_id>').innerHTML += msg.data + "<br>";
});
});
Finally, on the Flask server side, we need to create the SocketIO
object as follows:
socketio = SocketIO(app, message_queue='redis://')
Then run Flask with socketio.run(app,host='<ip>',port=<port>)
Upvotes: 4
Reputation: 67492
The problem is that each time a client sends the event named my event
to your server, you will try to start a new socket server on port 12345. Obviously this is only going to work the first time.
Have you seen the Emitting from an External Process section in the documentation?
The idea is that you can emit events to clients from any auxiliary process, which is exactly what you need. The solution involves installing a message queue (Redis, RabbitMQ), to which the Flask-SocketIO server and the external processes that need to have emit powers connect to.
Upvotes: 2