2015-09-22 2 views
1

Comment faire pour vider un événement flask-socketio de manière à ce que plusieurs lignes soient diffusées au client, par opposition à plusieurs lignes qui passent toutes en même temps? Je travaille avec Flask et flask-socketIO pour créer une application Web qui permet aux utilisateurs de jouer aux échecs contre les IA d'échecs open source, comme gnuchess et astucieux. Les IA d'échecs impriment leur "pensée" comme stdout au terminal serveur, mais j'utilise flask-socketIO pour émettre cette pensée à l'utilisateur.flask et flask-socketio vider tous les événements d'émission

Tout est configuré et fonctionne, mais le problème que j'ai est que chaque ligne de la pensée passe par un gros morceau, par opposition à la sortie de chaque ligne individuelle comme l'AI l'imprime.

Par exemple, lorsque vous jouez contre gnuchess, les impressions du serveur penser comme ceci:

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 

Et ces lignes afflueront vers mon serveur. Sur le côté client, j'émets les lignes AI, qui apparaissent au client (en ce moment) comme ul, qui ressemble à ceci:

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... 

Voici le code correspondant:

@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) 

Le problème ici est que tous les événements socketio.emit apparaissent comme un gros morceau de texte après le retour de la route du flacon. Peut-être qu'ils se coincent dans un tampon? Y a-t-il un moyen de les débusquer? L'IA "print" pense: "+ le code de ligne envoie au serveur de nombreuses lignes de texte, une ligne à la fois, à la sortie de l'IA, mais le code de socketio.emit arrive tout de suite à le client, au lieu de diffusion en ligne par ligne.

Toutes les idées?

Répondre

1

Utilisez eventlet.sleep(0) après votre déclaration socketio.emit().

Bien sûr, vous aurez à import eventlet.

Source:https://github.com/miguelgrinberg/Flask-SocketIO/issues/141

+0

lol merci pour la réponse. Ce convo que vous avez placé là est en fait ma convo avec Miguel. –

+0

Haha sympa Je n'ai pas attrapé c'était toi: p –

0

d'abord importer l'objet socketio (assurez-vous que les points de chemin à l'endroit où vous le créez)

from .. import socketio 

utilise alors

socketio.sleep(0) 

J'ai créé une fonction pour faire le sommeil pour moi :)

def send_status(data): 
    emit('status', data, json=True) 
    socketio.sleep(0) 

ca l'attacher avec la chaîne que je veux envoyer comme JSON

elehelper.send_status({'code': 201, 'message': 'Jana\'s skull stripper started!'})