diff --git a/lib/eventsource.js b/lib/eventsource.js index 93628b4..43448c2 100644 --- a/lib/eventsource.js +++ b/lib/eventsource.js @@ -17,6 +17,12 @@ function EventSource(url) { } }); + Object.defineProperty(this, 'url', { + get: function() { + return url; + } + }); + var self = this; self.reconnectInterval = 1000; var options = require('url').parse(url); @@ -33,8 +39,13 @@ function EventSource(url) { setTimeout(connect, self.reconnectInterval); } + var lastEventId = ''; var req; function connect() { + if (lastEventId != '') { + options.headers = { 'last-event-id': lastEventId }; + } + req = http.request(options, function(res) { readyState = EventSource.OPEN; _emit('open'); @@ -53,6 +64,7 @@ function EventSource(url) { if (data == '' || (message.event != null && message.event == '')) { return; } + if (message.id) lastEventId = message.id; _emit(message.event || 'message', new MessageEvent(data)); }); }); @@ -62,6 +74,7 @@ function EventSource(url) { }); req.on('error', onConnectionClosed); + req.setNoDelay(true); req.end(); } connect(); diff --git a/test/eventsource_test.js b/test/eventsource_test.js index 3bccb8b..4641b91 100644 --- a/test/eventsource_test.js +++ b/test/eventsource_test.js @@ -2,14 +2,15 @@ var http = require('http'); var EventSource = require('eventsource'); var port = 20000; -function createServer(chunks, callback) { +function createServer(chunks, callback, onreq) { var responses = []; var server = http.createServer(function (req, res) { + if (onreq) onreq(req); res.writeHead(200, {'Content-Type': 'text/event-stream'}); chunks.forEach(function(chunk) { res.write(chunk); }); - res.end(); + res.write(':'); // send a dummy comment to ensure that the response is flushed responses.push(res); }); function close(closed) { @@ -263,7 +264,43 @@ exports['Reconnect'] = { }); }; }); - } + }, + + 'send Last-Event-ID http header when id has previously been passed in an event from the server': function(test) { + createServer(['id: 10\ndata: Hello\n\n'], function(closeFirstServer) { + var headers = null; + var es = new EventSource('http://localhost:' + port); + es.onmessage = function(m) { + closeFirstServer(function() { + createServer([], function(close) { + es.onopen = function() { + test.equal('10', headers['last-event-id']); + es.close(); + close(test.done); + }; + }, function(req) { headers = req.headers; }); + }); + }; + }); + }, + + 'does not send Last-Event-ID http header when id has not been previously sent by the server': function(test) { + createServer(['data: Hello\n\n'], function(closeFirstServer) { + var headers = null; + var es = new EventSource('http://localhost:' + port); + es.onmessage = function(m) { + closeFirstServer(function() { + createServer([], function(close) { + es.onopen = function() { + test.equal('undefined', typeof headers['last-event-id']); + es.close(); + close(test.done); + }; + }, function(req) { headers = req.headers; }); + }); + }; + }); + }, }; exports['readyState'] = { @@ -323,6 +360,25 @@ exports['readyState'] = { }, }; +exports['Properties'] = { + setUp: function(done) { + port++; + done(); + }, + + 'url exposes original request url': function(test) { + createServer([], function(close) { + var url = 'http://localhost:' + port; + var es = new EventSource(url); + es.onopen = function() { + test.equal(url, es.url); + es.close(); + close(test.done); + } + }); + }, +}; + exports['Events'] = { setUp: function(done) { port++;