From 487e5bc2232adf6cb50c15f55c9012281a8c0d28 Mon Sep 17 00:00:00 2001 From: Harry Mills Date: Wed, 6 Dec 2017 17:15:07 -0500 Subject: [PATCH 1/4] Add ability to send data wrapped up as JSON --- README.md | 4 +++- index.js | 12 +++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7f8a32b..2709d9b 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ This middleware will keep the request stream open indefinitely, pad the initial Detailed information on how to setup the browser/client can be found [here][1]. +The client can be forced to disconnect by calling res.end(). + Installation -------- @@ -29,4 +31,4 @@ app.get('/events', sse, function(req, res) { }); ``` - [1]: https://developer.mozilla.org/en-US/docs/Server-sent_events/Using_server-sent_events \ No newline at end of file + [1]: https://developer.mozilla.org/en-US/docs/Server-sent_events/Using_server-sent_events diff --git a/index.js b/index.js index 7513a77..170f3a8 100644 --- a/index.js +++ b/index.js @@ -16,6 +16,10 @@ function sse(req, res, next) { res.flush(); } }; + res.sseData = function sseData(data) { + res.sse('data: ' + JSON.stringify(data) + '\n\n'); + this.isReady.reject(); + }; // write 2kB of padding (for IE) and a reconnection timeout // then use res.sse to send to the client @@ -27,10 +31,12 @@ function sse(req, res, next) { res.sse(':keep-alive\n\n'); }, 20000); - // cleanup on close - res.on('close', function close() { + // cleanup on close and finish + function cleanup() { clearInterval(keepAlive); - }); + } + res.on('close', cleanup); + res.on('finish', cleanup); next(); } From bf8e234de8725a3232ff57f04669670e9a68cf05 Mon Sep 17 00:00:00 2001 From: Harry Mills Date: Fri, 8 Dec 2017 10:50:14 -0500 Subject: [PATCH 2/4] Add support for named events --- .gitignore | 1 + index.js | 4 ++-- package.json | 17 ++++++++++------- yarn.lock | 30 ++++++++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 yarn.lock diff --git a/.gitignore b/.gitignore index 3027d2d..bc723ee 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ RCSLOG SCCS _$* _svn +node_modules diff --git a/index.js b/index.js index 170f3a8..9d2f3cb 100644 --- a/index.js +++ b/index.js @@ -16,9 +16,9 @@ function sse(req, res, next) { res.flush(); } }; - res.sseData = function sseData(data) { + res.sseEvent = function sseEvent(name, data) { + res.sse('event: ' + name + '\n'); res.sse('data: ' + JSON.stringify(data) + '\n\n'); - this.isReady.reject(); }; // write 2kB of padding (for IE) and a reconnection timeout diff --git a/package.json b/package.json index 21389c1..64b6b34 100644 --- a/package.json +++ b/package.json @@ -11,11 +11,14 @@ "url": "https://github.com/zacbarton/node-server-sent-events" }, "keywords": [ - "express", - "middleware", - "eventsource", - "sse", - "server-sent", - "events" - ] + "express", + "middleware", + "eventsource", + "sse", + "server-sent", + "events" + ], + "devDependencies": { + "eventsource": "^1.0.5" + } } diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..e944183 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,30 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +eventsource@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.0.5.tgz#1f012c9df0bd8832fd6b1744fea00ccdd479f046" + dependencies: + original "^1.0.0" + +original@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/original/-/original-1.0.0.tgz#9147f93fa1696d04be61e01bd50baeaca656bd3b" + dependencies: + url-parse "1.0.x" + +querystringify@0.0.x: + version "0.0.4" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-0.0.4.tgz#0cf7f84f9463ff0ae51c4c4b142d95be37724d9c" + +requires-port@1.0.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + +url-parse@1.0.x: + version "1.0.5" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.0.5.tgz#0854860422afdcfefeb6c965c662d4800169927b" + dependencies: + querystringify "0.0.x" + requires-port "1.0.x" From 2c12016c4e9bfc452e478bab784e417d1c535c4f Mon Sep 17 00:00:00 2001 From: Harry Mills Date: Fri, 8 Dec 2017 11:00:05 -0500 Subject: [PATCH 3/4] Refactor sse to an object --- index.js | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/index.js b/index.js index 9d2f3cb..3ce1f21 100644 --- a/index.js +++ b/index.js @@ -8,32 +8,44 @@ function sse(req, res, next) { res.status(200); // export a function to send server-side-events - res.sse = function sse(string) { + function send(string) { res.write(string); - // support running within the compression middleware if (res.flush && string.match(/\n\n$/)) { res.flush(); } - }; - res.sseEvent = function sseEvent(name, data) { - res.sse('event: ' + name + '\n'); - res.sse('data: ' + JSON.stringify(data) + '\n\n'); + } + + function event(event, data) { + send('event: ' + event + '\n'); + send('data: ' + JSON.stringify(data) + '\n\n'); + } + + res.sse = { + send: send, + event: event, + keepAlive: function keepAlive() { + send(':keep-alive\n\n'); + }, + error: function error(message) { + send('data: ' + JSON.stringify({ type: 'error', message: message }) + '\n\n'); + }, + set: function set(name, value) { + event(name, { type: 'set', value: value }); + }, }; // write 2kB of padding (for IE) and a reconnection timeout // then use res.sse to send to the client res.write(':' + Array(2049).join(' ') + '\n'); - res.sse('retry: 2000\n\n'); + res.sse.send('retry: 2000\n\n'); // keep the connection open by sending a comment - var keepAlive = setInterval(function() { - res.sse(':keep-alive\n\n'); - }, 20000); + var keepAliveTimer = setInterval(res.sse.keepAlive, 20000); // cleanup on close and finish function cleanup() { - clearInterval(keepAlive); + clearInterval(keepAliveTimer); } res.on('close', cleanup); res.on('finish', cleanup); From d539b804ddb7bc12a18d37e949ebe6556fc64331 Mon Sep 17 00:00:00 2001 From: Harry Mills Date: Fri, 8 Dec 2017 11:31:31 -0500 Subject: [PATCH 4/4] Remove deprecation warning --- index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 3ce1f21..6ab71bd 100644 --- a/index.js +++ b/index.js @@ -11,8 +11,8 @@ function sse(req, res, next) { function send(string) { res.write(string); // support running within the compression middleware - if (res.flush && string.match(/\n\n$/)) { - res.flush(); + if (res.flushHeaders && string.match(/\n\n$/)) { + res.flushHeaders(); } }