How do you flush a flask-socketio emit event so that multiple lines stream to the client, as opposed to multiple lines all coming through at one time?
I'm working with Flask and flask-socketIO to make a web app that let's users play chess against open source chess AI's, like gnuchess and crafty. The chess AI's print their "thinking" as stdout to the server terminal, but I am using flask-socketIO to emit that thinking to the user.
It's all setup and works, but the problem I have is that each line of the thinking all comes through in one big chunk, as opposed to outputting each individual line as the AI prints it.
For example, when playing against gnuchess, the server prints thinking like this:
AI thinking: Thinking...
AI thinking: 1 +4 0 2 a5
AI thinking: 1 +9 0 4 b5
AI thinking: 1 +51 0 8 d5
AI thinking: 1 +53 0 21 Nc6
AI thinking: 2 -1 0 47 Nc6 Nc3
AI thinking: 3 +53 0 155 Nc6 Nc3 Nf6
AI thinking: 4 -1 0 613 Nc6 Nf3 Nf6 Nc3
And these lines stream to my server. On the client-side, I emit the AI lines, which show up to the client (right now) as a ul, which looks like this:
4 -1 0 613 Nc6 Nf3 Nf6 Nc3
3 +53 0 155 Nc6 Nc3 Nf6
2 -1 0 47 Nc6 Nc3
1 +53 0 21 Nc6
1 +51 0 8 d5
1 +9 0 4 b5
1 +4 0 2 a5
Thinking...
Here's the relevant code:
@main.route('/getpythondata')
def get_python_data():
# gets current proc by finding user's most recent game...
current_game = get_current_game(current_user)
current_proc = get_current_proc(current_game)
line = current_proc.stdout.readline().rstrip()
socketio.emit(
'echo',
{'echo': line})
# for gnu chess
if current_game.ai == "GNU chess":
while ("My move is" not in line):
socketio.emit(
'echo',
{'echo': line})
print "AI thinking: " + line
line = current_proc.stdout.readline().rstrip()
colon_index = line.index(":")
line_length = len(line)
pythondata = line[(colon_index + 2):(line_length)]
current_game.cpu_moves.append(pythondata)
return json.dumps(pythondata)
The problem here is that all the socketio.emit events come through as one big chunk of text after the flask route returns. Maybe they're getting stuck in a buffer? Is there a way to flush them out?
The "print "AI thinking:" + line code streams to the server many lines of text, one line at a time, right as the AI outputs them. But, the socketio.emit code all comes through at once to the client, instead of streaming out line-by-line.
Any ideas?
Use eventlet.sleep(0)
after your socketio.emit()
statement.
Of course you'll have to import eventlet
.
Source: https://github.com/miguelgrinberg/Flask-SocketIO/issues/141
First import the socketio object (make sure the path points to where you create it)
from .. import socketio
then use
socketio.sleep(0)
I created a function to do the sleeping for me :)
def send_status(data):
emit('status', data, json=True)
socketio.sleep(0)
calling it with the string I want to send as a JSON
elehelper.send_status({'code': 201, 'message': 'Jana\'s skull stripper started!'})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With