Reputation: 39
I've set up an event emitter in a node.js/express application. The events it emits, are caught by a front-end listener. The thing is that although I can see that emit is called once, the emitter emits the same event up to 4 times. In addition, although in general the events are received by the listener and acted upon, sometimes nothing happens. Does anyone have an idea about what I'm doing wrong?
Backend:
app.get('/getStatus', isLoggedIn, function(req, res){
res.writeHead(200, {'Content-Type': 'text/event-stream'});
progressEmitter.on('status',function(newState, job_id, fTime, jobLink){
console.log('Updated state to : ' + newState + ' for job ' + job_id );
res.write("event: state\n");
res.write(`data:${newState},${job_id},${fTime},${jobLink}\n\n`);
console.log(`Emitted state change data! :${newState},${job_id},${fTime},${jobLink}\n\n`);
});
});
Frontend:
$(document).ready(function () {
var state = [];
var source = new EventSource('getStatus');
source.addEventListener('state', function(e) {
state = e.data.split(',');
for (var ajob in jobsReceived){
if (jobsReceived[ajob].id == state[1]) {
jobsReceived[ajob].status = state[0];
jobsReceived[ajob].finished_time = state[2];
console.log(state[0]);
if (state[0] === 'saved') jobsReceived[ajob].link = state[3];
break;
}
}
$('#table').bootstrapTable('updateByUniqueId', {
id: state[1],
row: {
status: format_status(state[0]),
finished_time: state[2],
link: state[0] === 'saved'? state[3]:''
}
});
});
Upvotes: 0
Views: 1400
Reputation: 39
After spending time on other issues, I decided to revisit it with a clear head and finally got the solution. I am posting it here, in case somebody has the same issue.
What happens here, is that a listener is added each time the progressEmitter.on() is called. When the event is emitted, all listeners are run.
In order to remedy this, the listener has to be removed when the request is closed. This is done by calling emitter.removeListener(). Since the parameters needed by this function are the event name and the listener function, it is easier to name the listener function. Thus, the backend code changes as follows:
app.get('/getStatus', isLoggedIn, function(req, res){
res.writeHead(200, {'Content-Type': 'text/event-stream'});
function statusEvent(newState, job_id, fTime, jobLink){
console.log('Updated state to : ' + newState + ' for job ' + job_id );
res.write("event: state\n");
res.write(`data:${newState},${job_id},${fTime},${jobLink}\n\n`);
console.log(`Emitted state change data!');
}
progressEmitter.on('status',statusEvent);
req.on('close', function(){
progressEmitter.removeListener('event', statusEvent);
})
})
Upvotes: 1