2017-10-30 2 views
3

Ich habe einen Flask-SocketIO Python-Server erstellt, der Daten von einem socket.io JavaScript-Client protokollieren sollte.Socket.IO Emit Sendeverzögerung

Server:

from flask import Flask, render_template 
from flask_socketio import SocketIO 

app = Flask(__name__) 
socketio = SocketIO(app) 

@socketio.on('connect') 
def handle_connect(): 
    print 'Connected' 

@socketio.on('disconnect') 
def handle_disconnect(): 
    print 'Disconnected' 

@socketio.on('start') 
def handle_start(): 
    print 'Start' 

@socketio.on('log') 
def handle_log(data): 
    print('Log: ' + data) 

if __name__ == '__main__': 
    socketio.run(app) 

Auftraggeber:

<script src="socket.io.js"></script> 

<script> 
    function sleep(ms) { 
     var unixtime_ms = new Date().getTime(); 
     while(new Date().getTime() < unixtime_ms + ms) {} 
    } 

    var socket = io.connect('http://127.0.0.1:5000', {'forceNew':true }); 
    socket.on('connect', function() 
    { 
     socket.emit('start'); 
     socket.emit('log', '1'); 
     socket.emit('log', '2'); 
     socket.emit('log', '3'); 

     sleep(3000) 
    }); 
</script> 

Statt zu sehen, die Server-Druck "Start", "Log: 1", "Log: 2" und "Log: 3" sofort .

Der Server druckt nur "Start" und druckt nach 3 Sekunden alle anderen Nachrichten in einer Aufnahme aus.

Dies ist ein Problem, da ich Echtzeitprotokollierung benötige und es mir nicht leisten kann, alle Protokolle am Ende der Ausführung in einem Durchgang zu empfangen.

Irgendeine Idee, warum das passiert und was ist der richtige Weg, um diesen einfachen Protokollserver zu implementieren?

+2

Funktioniert es, wenn Sie den Aufruf 'sleep (3000)' auskommentieren? – Miguel

+0

Es funktioniert, weil die Funktion endet, und nur wenn die Funktion endet, werden alle anderen emittiert. Ich brauche das andere emittiert in Echtzeit und nicht nur, wenn die Funktion endet. – Michael

+1

Die Tatsache, dass die Funktion endet, ist irrelevant. Der Schlüssel hier ist, dass Sie blockieren, wenn Sie 'sleep()' aufrufen. Sie können nicht blockieren, da JS eine asynchrone Sprache ist. – Miguel

Antwort

-1

Die sleep() Funktion, die Sie verwenden, ist wirklich schlecht für JavaScript, da Sie nicht wirklich schlafen, aber beschäftigt-warten. Das bedeutet, dass die CPU während dieser 3 Sekunden eingeschaltet ist, sodass andere Tasks, die eine CPU benötigen, verzögert werden.

Wenn Sie 3 Sekunden warten, bevor etwas anderes zu tun, empfehle ich Ihnen ein Timer-Objekt verwenden:

window.setTimeout(function() { alert('do something!'); }, 3000); 

Wenn Sie ein Timeout Schlaf verwenden Sie die CPU während der Wartezeit der Freigabe werden, und dass Der JS-Scheduler kann ihn anderen Aufgaben zuweisen, die ihn benötigen, z. B. solche, die Socket.IO unterstützen.

Hoffe, das hilft!

+0

Dies ist unabhängig von meiner Frage, der Punkt ist, dass die erste emittiert ("Start") passiert sofort (in Echtzeit), und die anderen emittiert aus irgendeinem Grund "stecken", bis die Funktion endet. Erst wenn die Funktion endet, erscheinen alle anderen. – Michael

+1

Danke für den Downvote. Sie scheinen nicht vertraut zu sein, wie asynchrone Systeme funktionieren, also schlage ich vor, dass Sie weiterlesen, um zu verstehen, warum Ihre 'sleep()' Funktion tatsächlich das Problem ist. – Miguel

+0

Ich schätze Ihre Hilfe, aber Schlaf war nur ein Beispiel, um meine Frage zu vereinfachen. Mein ursprünglicher Code hat "window.location.reload()" statt Schlaf. Da die Ausstrahlungsanrufe nicht sofort erfolgen (sie sind asynchron), befinden sich der Neuladeprozess und der Ausgesendeanruf in einem Race-Zustand, und einige senden den Server erfolgreich an, einige werden jedoch verpasst, weil die Seite neu geladen wurde. Von dem, was ich gesehen habe, emittieren Pufferanforderungen (1-n) und spült sie nur zu bestimmten Zeiten (Ende der Funktion zum Beispiel). Ich brauche einen Weg, um sicherzustellen, dass die Emission abgespült wird, daher meine Frage und den Schlaf als eine Vereinfachung zu verwenden. – Michael

Verwandte Themen