I am developing a logging application and am experiencing some delays (10-20 sec) when messages get sent from the server to the browser. I am using 'socketio.emit' because I don't need the client to talk to the server except for establishing its connection to the socket. For this reason I am not using a socketio.on decorator for the handleNewLog function. Server side and client side code below:
app = Flask(__name__)
socketio = SocketIO(app)
@socketio.on('connected')
def consume(message):
print message
@app.route('/')
def allLogs():
content = {"timestamps": [1], "messages": ["hello"], "containers": ["container"], "levels": [1]}
return render_template('index.html', levels=content['levels'], timestamps=content['timestamps'], containers=content['containers'], messages=content['messages'])
def handleNewLog(client, userdata, message):
msg = json.loads(message.payload.decode('utf-8'))
container = msg["container"]
timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
logMessage = msg["log-message"]
msgLogLevel = msg["log-level"].upper()
try:
socketio.emit('new-log', {'data': {'logLevel': msgLogLevel, 'container': container, 'logMessage': logMessage}}, broadcast = False)
print "hello"
except Exception as err:
print err
print 'Could not append log'
$(document).ready(function(){
var socket = io.connect('http://' + document.domain + ':' + location.port + location.pathname);
console.log('hello world');
socket.on('new-log', function(msg) {
console.log("new log");
$('#level').append('<p style="margin:0 0 0 0;">'+ msg.data.logLevel + '</p>');
$('#timestamp').append('<p style="margin:0 0 0 0;">FAKE:TIME:STAMP</p>');
$('#container').append('<p style="margin:0 0 0 0;">'+ msg.data.container + '</p>');
$('#message').append('<p style="margin:0 0 0 0;">'+ msg.data.logMessage + '</p>');
});
});
I tested sending a message with a socketio.on decorator and using 'emit' and it the client received the message instantly. Any insight as to why messages using socketio.emit are being delayed?
Are you using eventlet or gevent with this application? That is important in the context of blocking and delays. Also, can you include the code that calls the handleNewLog() function? I suspect you may be blocking there.
I have both installed and from previous comments that I have read, the priority goes to gevent I think. The code that calls handleNewLog is below. Its being passed in as a callback function for a MQTT client. The client will call handleNewLog when it receives a message from the MQTT broker.
address = 'localhost'
mqtt = MqttClient(address, 1883, handleNewLog) # mqtt client that will connect,pub,sub to mqtt broker
I don't have experience with mqtt myself, but I have heard from users having problems combining it with eventlet or gevent. At the very least, you should make sure the Python standard library is monkey patched, but even with that, it is quite possible that things won't work.
Note that if both eventlet and gevent are installed, eventlet takes precedence.
monkey patching did the trick! Just had to import eventlet and call the monkey patch function. Appreciate the help!!
Most helpful comment
monkey patching did the trick! Just had to import eventlet and call the monkey patch function. Appreciate the help!!