Reputation: 1686
I have a Flask Python webserver with websockets (socketIO).
I want to run a command and stream the output to a <p id='streaming_text'>
HTML element.
This is my code:
HTML
div class='streaming'>
<p id="streaming_text"></p>
</div>
JQuery
var socket = io.connect('http://' + document.domain + ':' + location.port + '/stream')
socket.on('message', function(msg){
$('#streaming_text').append(msg);
})
...
jqxhr.done(function(cmd){
socket.send(cmd)
return false;
})
Python
@socketio.on('message', namespace='/stream')
def stream(cmd):
# Streams output of a command
print("Received msg %s from JS socket" % cmd)
print("Executing %s" % cmd)
from shelljob import proc
g = proc.Group()
p = g.run(cmd)
while g.is_pending():
lines = g.readlines()
for proc, line in lines:
print(line)
send(line, namespace='/stream')
In the browser console I see all the send(line)
are executed at the same time: when the command finishes running. The print(line)
, however, shows me the output of my command in real-time.
The commands I run take in average 15 minutes to run, so it'd be a bad user experience to have to wait for that long without seeing any output.
How can I send those messages immediately without having to wait for the end of the command ?
Upvotes: 1
Views: 1730
Reputation: 1686
To answer my own question, I solved this problem by adding: eventlet.sleep(0)
after each send
call in the Python code.
The new code is as such:
Python
@socketio.on('message', namespace='/stream')
def stream(cmd):
# Streams output of a command
print("Received msg %s from JS socket" % cmd)
print("Executing %s" % cmd)
from shelljob import proc
g = proc.Group()
p = g.run(cmd)
while g.is_pending():
lines = g.readlines()
for proc, line in lines:
print(line)
send(line, namespace='/stream')
Apparently this seems to flush the messages, so actually sends them right away to whatever code you're using to receive them, in my case a JavaScript (JQuery) script.
Source: https://github.com/miguelgrinberg/Flask-SocketIO/issues/141
Upvotes: 2