I'm using MEAN and I'm trying to receive events from server side. For that, Im using EventSource but It just doesn't work.
I see how connection is open but I don't get any message from server. I can see in Node console how the messages are being sent but in client side there's nothing (browser console).
I'm a bit lost as I'm following all the tutorials I've found, but using exactly the same code it just doesn't work.
In client side, this is my AngularJS code:
var source = new EventSource('/api/payments/listen');
source.addEventListener('open', function(e) {
console.log('CONNECTION ESTABLISHED');
}, false);
source.addEventListener('message', function (e) {
$scope.$apply(function () {
console.log('NOTIFICATION');
console.log(e.data);
});
}, false);
source.onmessage = function (e) {
console.log('NOTIFICATION!');
console.log(e);
};
source.addEventListener('error', function(e) {
if (e.readyState === EventSource.CLOSED) {
console.log('CONNECTION CLOSED');
}
}, false);
Server side code:
exports.listen = function (req, res) {
if (req.headers.accept && req.headers.accept === 'text/event-stream') {
if ( req.url === '/api/payments/listen' ) {
sendSSE(req, res);
}
else {
res.writeHead(404);
res.end();
}
}
else
res.end();
};
function sendSSE(req, res) {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
var id = (new Date()).toLocaleTimeString();
// Sends a SSE every 5 seconds on a single connection.
setInterval(function() {
constructSSE(res, id, data);
}, 5000);
constructSSE(res, id, data);
}
function constructSSE(res, id, data) {
res.write('id: ' + id + '\n');
res.write('data: ' + JSON.stringify(data) + '\n\n');
}
Any suggestion? Any tip?
Edit
I don't know what was causing the issue, but I have got it to work using Simple-SSE, a useful and little library for server side events.
Now, it is working as expected.
Here it is the link for those who wants to give it a try:
Thanks =)
I'm using MEAN and I'm trying to receive events from server side. For that, Im using EventSource but It just doesn't work.
I see how connection is open but I don't get any message from server. I can see in Node console how the messages are being sent but in client side there's nothing (browser console).
I'm a bit lost as I'm following all the tutorials I've found, but using exactly the same code it just doesn't work.
In client side, this is my AngularJS code:
var source = new EventSource('/api/payments/listen');
source.addEventListener('open', function(e) {
console.log('CONNECTION ESTABLISHED');
}, false);
source.addEventListener('message', function (e) {
$scope.$apply(function () {
console.log('NOTIFICATION');
console.log(e.data);
});
}, false);
source.onmessage = function (e) {
console.log('NOTIFICATION!');
console.log(e);
};
source.addEventListener('error', function(e) {
if (e.readyState === EventSource.CLOSED) {
console.log('CONNECTION CLOSED');
}
}, false);
Server side code:
exports.listen = function (req, res) {
if (req.headers.accept && req.headers.accept === 'text/event-stream') {
if ( req.url === '/api/payments/listen' ) {
sendSSE(req, res);
}
else {
res.writeHead(404);
res.end();
}
}
else
res.end();
};
function sendSSE(req, res) {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
var id = (new Date()).toLocaleTimeString();
// Sends a SSE every 5 seconds on a single connection.
setInterval(function() {
constructSSE(res, id, data);
}, 5000);
constructSSE(res, id, data);
}
function constructSSE(res, id, data) {
res.write('id: ' + id + '\n');
res.write('data: ' + JSON.stringify(data) + '\n\n');
}
Any suggestion? Any tip?
Edit
I don't know what was causing the issue, but I have got it to work using Simple-SSE, a useful and little library for server side events.
Now, it is working as expected.
Here it is the link for those who wants to give it a try: https://github./Lesterpig/simple-sse
Thanks =)
Share Improve this question edited Oct 31, 2016 at 12:30 Rubén Jiménez asked Oct 28, 2016 at 12:19 Rubén JiménezRubén Jiménez 1,8455 gold badges21 silver badges30 bronze badges 6-
In PHP you would use an infinite while loop with
sleep
, because otherwise the thread will close. Maybe it's the same? – Emil S. Jørgensen Commented Oct 28, 2016 at 12:36 - Where are you sending the server side event? I don't see an event being called, I see a lot of client side listeners, no emit from server. – Matt Greenberg Commented Oct 28, 2016 at 14:20
- @EmilS.Jørgensen I'll check it out but none of the implementation examples I've found use something like that. Besides, I don't see any "CONNECTION CLOSED" in client side after connection is established with server. Thanks! – Rubén Jiménez Commented Oct 28, 2016 at 21:44
- @magreenberg It is supposedly a stream so you write something in the pipe and the content goes directly to client side. In this case, that is acplished by "res.write". Anyway, I'll check it out as well. – Rubén Jiménez Commented Oct 28, 2016 at 21:44
- Have tried calling /api/payments/listen with curl? Does it behave as you would expect? – baynezy Commented Oct 30, 2016 at 9:18
1 Answer
Reset to default 17Hope this helps anyone that was having the same issue I was. I came to this question, after not being able to receive messages from the server although everything in my code seemed to be exactly how it was supposed to. After seeing that this library helped I dug into source code and found my answer. If you are using any pression library such as I was in my express app, you need to flush the response after the write. other wise the pression doesn't send the message as the protocol expects. e.g. res.write("data:hi\n\n") res.flush()