Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Server Side Events (SSE) not reaching client side

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.com/Lesterpig/simple-sse

Thanks =)

like image 360
Rubén Jiménez Avatar asked Oct 28 '16 12:10

Rubén Jiménez


1 Answers

Hope 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 compression library such as I was in my express app, you need to flush the response after the write. other wise the compression doesn't send the message as the protocol expects. e.g. res.write("data:hi\n\n") res.flush()

like image 67
Jay Garzon Avatar answered Nov 14 '22 03:11

Jay Garzon