Giter Club home page Giter Club logo

eventsource's Introduction

EventSource npm versionNPM Downloads

Build

This library is a pure JavaScript implementation of the EventSource client. The API aims to be W3C compatible.

You can use it with Node.js or as a browser polyfill for browsers that don't have native EventSource support.

Install

npm install eventsource

Example

npm install
node ./example/sse-server.js
node ./example/sse-client.js    # Node.js client
open http://localhost:8080      # Browser client - both native and polyfill
curl http://localhost:8080/sse  # Enjoy the simplicity of SSE

Browser Polyfill

Just add example/eventsource-polyfill.js file to your web page:

<script src=/eventsource-polyfill.js></script>

Now you will have two global constructors:

window.EventSourcePolyfill
window.EventSource // Unchanged if browser has defined it. Otherwise, same as window.EventSourcePolyfill

If you're using webpack or browserify you can of course build your own. (The example/eventsource-polyfill.js is built with webpack).

Extensions to the W3C API

Setting HTTP request headers

You can define custom HTTP headers for the initial HTTP request. This can be useful for e.g. sending cookies or to specify an initial Last-Event-ID value.

HTTP headers are defined by assigning a headers attribute to the optional eventSourceInitDict argument:

var eventSourceInitDict = {headers: {'Cookie': 'test=test'}};
var es = new EventSource(url, eventSourceInitDict);

Allow unauthorized HTTPS requests

By default, https requests that cannot be authorized will cause the connection to fail and an exception to be emitted. You can override this behaviour, along with other https options:

var eventSourceInitDict = {https: {rejectUnauthorized: false}};
var es = new EventSource(url, eventSourceInitDict);

Note that for Node.js < v0.10.x this option has no effect - unauthorized HTTPS requests are always allowed.

HTTP status code on error events

Unauthorized and redirect error status codes (for example 401, 403, 301, 307) are available in the status property in the error event.

es.onerror = function (err) {
  if (err) {
    if (err.status === 401 || err.status === 403) {
      console.log('not authorized');
    }
  }
};

HTTP/HTTPS proxy

You can define a proxy option for the HTTP request to be used. This is typically useful if you are behind a corporate firewall.

var es = new EventSource(url, {proxy: 'http://your.proxy.com'});

License

MIT-licensed. See LICENSE

eventsource's People

Contributors

3rd-eden avatar adrai avatar afroozeh avatar ajinkyarajput avatar akwd22 avatar alexhladin avatar aslakhellesoy avatar bitdeli-chef avatar david-mark avatar dijonkitchen avatar dpatty avatar einaros avatar ericlu88 avatar evanshortiss avatar fire- avatar flowersinthesand avatar frozencow avatar honkinggoose avatar joeflateau avatar joeybaker avatar jzaefferer avatar kmayer avatar neftaly avatar pfreixes avatar piranna avatar qqueue avatar rexxars avatar scalawilliam avatar web2solutions avatar wkovacs64 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

eventsource's Issues

Tests are hanging

This is on 99e6cc3 - tried both Node 0.6.1 and o.6.10.

$ make

eventsource_test
✔ Messages - one one-line message in one chunk
✔ Messages - one one-line message in two chunks
✔ Messages - two one-line messages in one chunk
✔ Messages - one two-line message in one chunk
✔ Messages - really chopped up unicode data
✔ Messages - accepts CRLF as separator
✔ Messages - accepts CR as separator
✔ Messages - delivers message with explicit event
✔ Messages - comments are ignored
✔ Messages - empty comments are ignored
✔ Messages - empty data field causes entire event to be ignored
✔ Messages - empty event field causes entire event to be ignored
✔ HTTP Request - passes cache-control: no-cache to server
✔ HTTPS Support - uses https for https urls
✔ Reconnect - when server is down
[HANGS]

Method overriding when extends

class MyEventSource extends EventSource {
  close() {
    console.log('My close function call')
  }
}

const es = new MyEventSource(...)
es.close()

In the Browser (Chrome or Firefox) the output is:

My close function call

But in the NodeJS the output is:

undefined

Because my close function does not override the EventSource.close function.

Listening for all events

Dear,

Using this node to listen for named events works like a charm.
However I was wondering if it is also possible to listen for all events.

Have tried following without success:

eventSource.addEventListener('', callback);
eventSource.addEventListener('*', callback);

Sometimes it is not clear to users which events are being send, especially when the default 'message' is replace by other custom events. In that case it would be nice to start listening for all events, and then later on filter only specific events...

Kind regards,
Bart Butenaers

Digest auth

I'm sorry about creating this issue, but I've searched around and couldn't find any answers, so I thought I'd ask here: is it possible to use EventSource in Node.js, against an API that requires digest authentication? If so, are there any examples out there? Thank you!

onConnectionClosed firing multiple times and connecting more than once (server restart)

onConnectionClosed is called for connection close and end.

connect is called twice
the first connect makes a request but before it can get a response
the 2nd connect is called. In both states readyState is CONNECTING
the 2nd connect makes a request
the first connect now gets a response and is connected
the 2nd connect now gets a response and is connected

restart the server again (we now get 4 connects) and this perpetuates.

blank lines parsing?

Trying to run a SSE server

https://github.com/tomkersten/sses-node-example

...that works with a browser against this module and I'm getting a parser error.

/home/rngadam/tradesparq/feynman/deps/sses-benchmark/node_modules/eventsource/lib/eventstream.js:58
    throw new Error(str);
          ^
Error: Parse error on line 1:
id: 1data: hello w
^
Expecting 'colon', 'char', 'space', got 'eol'
    at Object.parseError (/home/rngadam/tradesparq/feynman/deps/sses-benchmark/node_modules/eventsource/lib/eventstream.js:58:11)
    at Object.parse (/home/rngadam/tradesparq/feynman/deps/sses-benchmark/node_modules/eventsource/lib/eventstream.js:110:22)
    at Object.exports.parse (/home/rngadam/tradesparq/feynman/deps/sses-benchmark/node_modules/eventsource/lib/eventstream.js:363:56)
    at IncomingMessage.<anonymous> (/home/rngadam/tradesparq/feynman/deps/sses-benchmark/node_modules/eventsource/lib/eventsource.js:85:40)
    at IncomingMessage.EventEmitter.emit (events.js:88:17)
    at IncomingMessage._emitData (http.js:359:10)
    at HTTPParser.parserOnBody [as onBody] (http.js:123:21)
    at Socket.socketOnData [as ondata] (http.js:1366:20)
    at TCP.onread (net.js:403:27)

I think there might be a condition that is not taken into account by the parser:

http://www.w3.org/TR/2009/WD-eventsource-20091029/#event-stream-interpretation

If the line is empty (a blank line)
Dispatch the event, as defined below.

[...]

When the user agent is required to dispatch the event, then the user agent must act as follows:

If the data buffer is an empty string, set the data buffer and the event name buffer to the empty string and abort these steps.

Can't proxy through Squid: TCP_MISS/503 error

When connect to server directly, it works fine. When pass a proxy, squid tells TCP_MISS/503 error.
Source code:

const url = `https://${PostOpts.host}:${PostOpts.port}/sse`;
        if (params.proxy) {
            const proxy = params.proxy;
            console.log('EventSource proxy: ', proxy);
            this._source = new EventSource(url, {proxy: proxy});
        }

Console.log output:

EventSource proxy:  http://192.168.1.50:3128
Event { type: 'error', status: 503 }
Event { type: 'error' }

Squid output:

1497854565.761      3 192.168.1.51 TCP_MISS/503 4277 GET https://192.168.1.246/sse - HIER_DIRECT/192.168.1.246 text/html
1497854566.780      4 192.168.1.51 TCP_MISS/503 4277 GET https://192.168.1.246/sse - HIER_DIRECT/192.168.1.246 text/html
1497854567.795      6 192.168.1.51 TCP_MISS/503 4277 GET https://192.168.1.246/sse - HIER_DIRECT/192.168.1.246 text/html
1497854646.226      2 192.168.1.51 TCP_MISS/503 4277 GET https://192.168.1.246/sse - HIER_DIRECT/192.168.1.246 text/html
1497854647.254      7 192.168.1.51 TCP_MISS/503 4277 GET https://192.168.1.246/sse - HIER_DIRECT/192.168.1.246 text/html
1497854648.279      7 192.168.1.51 TCP_MISS/503 4277 GET https://192.168.1.246/sse - HIER_DIRECT/192.168.1.246 text/html

Parser error

got the following exception when trying the mentioned SSE example, with this lib (installed it via npm / also replaced the code in my npm_repo with the code from here)

manni:SSE-demo matzew$ node client.js

/Users/matzew/node_modules/eventsource/lib/eventstream.js:60
throw new Error(str);
^
Error: Parse error on line 1:
:
-^
Expecting 'colon', 'char', 'space', got 'eol'
at Object.parseError (/Users/matzew/node_modules/eventsource/lib/eventstream.js:60:11)
at Object.parse (/Users/matzew/node_modules/eventsource/lib/eventstream.js:137:22)
at Object.parse (/Users/matzew/node_modules/eventsource/lib/eventstream.js:401:56)
at IncomingMessage. (/Users/matzew/node_modules/eventsource/lib/eventsource.js:24:25)
at IncomingMessage.emit (events.js:67:17)
at HTTPParser.onBody (http.js:115:23)
at Socket.ondata (http.js:1124:24)
at TCP.onread (net.js:348:27)

Duplicate connection seen when the server goes down and comes up again

Lets suppose the eventsource client has connected to the server and is receiving messages.

Lets suppose the server goes down
The eventsource client callback onerror is fired
The eventsource client keeps re-trying to connect
The server comes online again
Observation - eventsource client now makes two connections to the server.

Further - each message that the server sends is received twice by the eventsource client, due to the duplicate connection.

Is the above not a valid usecase to be supported by the module?
Curious to know the reason why it was not considered?

Missing origin in message event

The specification states:

Create an event that uses the MessageEvent interface, with the event type message, which does not bubble, is not cancelable, and has no default action. The data attribute must be initialized to the value of the data buffer, the origin attribute must be initialized to the Unicode serialization of the origin of the event stream's final URL (i.e. the URL after redirects), and the lastEventId attribute must be initialized to the last event ID string of the event source. This event is not trusted.

Useful error messages

As it stands, binding to onerror isn't useful since it's not currently possible to know what exactly went wrong.

Parse fails on multibyte characters

The parser doesn't appear to work with multibyte characters like asian char sets:

Error: Parse error on line 2:
...uluren0724","body":"拜託這場一定要放youtube "}
-----------------------^
Expecting 'eol', 'colon', 'char', 'space', got 'INVALID'
Error: Parse error on line 2:
...k":"akasim","body":"沒錯 機體強弱不說"}
-----------------------^
Expecting 'eol', 'colon', 'char', 'space', got 'INVALID'
Error: Parse error on line 2:
...k":"d40301","body":"我現在都看實況不玩遊戲"}
-----------------------^
Expecting 'eol', 'colon', 'char', 'space', got 'INVALID'
Error: Parse error on line 2:
...panjimmy","body":"28沒人"}
-----------------------^
Expecting 'eol', 'colon', 'char', 'space', got 'INVALID'
Error: Parse error on line 2:
...zero751210","body":"西葛格晚上好wwwww"}
-----------------------^
Expecting 'eol', 'colon', 'char', 'space', got 'INVALID'
/home/fire/programming_projects/js/node/test/node_modules/eventsource/lib/eventstream.js:58
    throw new Error(str);
          ^
Error: Parse error on line 2:
...,"body":"c'est pas 3€ les 1k viewers le 
-----------------------^
Expecting 'eol', 'colon', 'char', 'space', got 'INVALID'
    at Object.parseError (/home/fire/programming_projects/js/node/test/node_modules/eventsource/lib/eventstream.js:58:11)
    at Object.parse (/home/fire/programming_projects/js/node/test/node_modules/eventsource/lib/eventstream.js:110:22)
    at Object.exports.parse (/home/fire/programming_projects/js/node/test/node_modules/eventsource/lib/eventstream.js:363:56)
    at IncomingMessage.<anonymous> (/home/fire/programming_projects/js/node/test/node_modules/eventsource/lib/eventsource.js:85:40)
    at IncomingMessage.EventEmitter.emit (events.js:95:17)
    at IncomingMessage.<anonymous> (_stream_readable.js:699:14)
    at IncomingMessage.EventEmitter.emit (events.js:92:17)
    at emitReadable_ (_stream_readable.js:382:10)
    at emitReadable (_stream_readable.js:377:5)
    at readableAddChunk (_stream_readable.js:142:7)

Grammar is ambiguous

To reproduce: make clobber lib/eventstream.js

./node_modules/.bin/jison -o lib/eventstream.js lib/eventstream.jison
Conflict in grammar: multiple actions possible when lookahead token is lf in state 16
- reduce by rule: eol -> cr
- shift token (then go to state 28)

States with conflicts:
State 16
  eol -> cr .lf #lookaheads= space char colon EOF lf cr
  eol -> cr . #lookaheads= space char colon EOF lf cr

See #6

Request error details hidden to client

Say we have an eventsource client connected to a server and receiving messages.

Il the server goes down, the onerror callback is invoked, which is fine, but the event that is passed only contains { type: 'error' }

Could it be possible to add more info to the event, like the original error code ('ECONNREFUSED' for instance) ?

Error behind proxy with Authentication

When trying to get a connection behind our companies proxy (which requires you to use username+password+url+port to access anything behind it) I get this weird error:

write EPROTO 101057795:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:openssl\ssl\s23_clnt.c:794:

Do you know if this is a currently supported feature? My proxy setting looks like this:

proxy: 'http://${this.proxy.user}:${this.proxy.password}@${this.proxy.address}'

Blank lines not read

Hi !
I've got a problem with blank lines parsing.
Assuming I want to send this message : "I am\na text.\n\nHello World!".
The server will encode it as :

data: I am\n
data: a text.\n
data: \n
data: Hello World!\n\n

But eventsource will parse it and give : "I am\na text.\nHello World!"
On Chrome, with the same server, I get the correct message.

Thank's !

readyState values are not defined on EventSource instance

CONNECTING, OPEN, CLOSED constants are not defined on the new EventSource(...) object.

EventSource.CONNECTING === 0  // true
EventSource.OPEN === 1  // true
EventSource.CLOSED === 2  // true

Which is what expected, but not the following:

let es = new EventSource(url)
es.CONNECTING === undefined  // true
es.OPEN === undefined  // true
es.CLOSED === undefined  // true

I have not found details about this in the specification, but in Firefox 50.1.0 and Chrome 57 it works. Comparing to WebSocket API, it also works the same way in the browsers.

close() doesn't terminate the connection when fetch is being used

EventSource's close() method does not close the underlying http connection when the http request uses the Fetch API (because a fetch can't be aborted). After having 6 EventSource's for a single origin (because the close() was failing in when switching between them) all requests are then queued.

This is happening in the latest versions of Chrome on Windows and possibly other browsers.

This is a flow on issue from the stream-http project outlined here.

I've created a PR#92 that resolves the issue by adding a mode property to the eventSourceInitDict that is 'disable-fetch' (actually you can pass any valid mode, this is the one that fixes this issue though) which forces the XHR to be used instead of the Fetch API and these are able to be aborted.

Connection is not closed by calling close()

Seems like on Chrome connection is not closed after calling close().
Chrome still shows in developer tools: "CAUTION: request is not finished yet!" for "cancelled" request.
Google Chrome Version 60.0.3112.90

May be related to #82

Non-standard reconnect behavior

I noticed a recent change causes a reconnect even if the server responds with a non-200 status code to the initial request. This is non-standard (https://html.spec.whatwg.org/multipage/comms.html#the-eventsource-interface):

Any other HTTP response code not listed here, as well as the cancelation of the fetch algorithm by the user agent (e.g. in response to window.stop() or the user canceling the network connection manually) must cause the user agent to fail the connection.

Failing the connection is defined as:

When a user agent is to fail the connection, the user agent must queue a task which, if the readyState attribute is set to a value other than CLOSED, sets the readyState attribute to CLOSED and fires a simple event named error at the EventSource object. Once the user agent has failed the connection, it does not attempt to reconnect!

I do see the following in the standard:

Clients will reconnect if the connection is closed; a client can be told to stop reconnecting using the HTTP 204 No Content response code.

I believe this means that if the initial request responded with 200 and then is closed, it may reconnect.

EventSource Hangs when client changes IP address

Hi,
I have a local node server (v8) connected to an external server using EventSource.
I can receive the events correctly but when my WAN address changes (dynamic IP from the ISP provider) I can no longer receive events. I also don't get any error event about this.
When I ask for readyState I always get OPEN.
The only option was to poll the server periodically and if I don't get an event in a certain amount of time I close the connection and create a new one. This obviously defeats the purpose of an event.

Is there another option to fix this behavior?
Thank you,
Emilio

eventSourceInitDict should pass all options to request

When using https, options allowed for request are hardcoded:

    if (isSecure) {
      options.key = eventSourceInitDict.key;
      options.cert = eventSourceInitDict.cert;
      options.passphrase = eventSourceInitDict.passphrase;
    }

However, some options are not supported such as : options.pfxand options.strictSSL.
eventSourceInitDict should have a field containing all request options, for example eventSourceInitDict.request.

old "last-event-id" used on reconnect

I am seeing the "last-event-id" header used on reconnect, but everytime it reconnects, it's using the original "last-event-id" value, even when subsequent events had been processed since the original connect.

scenario:

  • initialize eventsource with a last-event-id
  • begin listening and process some events
  • connection drops and reconnects using original "last-event-id"

Should be using the last event's id!

RSA Private key?

It may be nothing, but I was making a chrome extension last night and eventsource must have been an dependency of one of my dependencies.

Anyway chrome called my extension out with a warning saying that I probably don't want to put a key.pem file in my chrome extension.

Alarmed I found that eventsource contains a key.pem file the test directory.

Honestly I don't really know what eventsource is used for, but I assume this is maybe a mistake? Sorry if I am just ignorant to how this library works. Just thought I should check.

Discussion: Node version compatibility and browser support

Basic questions, really, but it has come up a few times lately when I take a stab at the issue list and PRs:

  • Which node versions should we support?
  • What is our goal in regards to browser support? Should this module attempt to be a polyfill for browsers without EventSource?

data not received in Safari until connection closed

I tried to chase down why this is happening but I can't figure it out. Safari never receives the "data" event, so messages are never received. Instead they are buffered somewhere and the browser receives them all at once if the server connection is severed.

I tried it with Yaffle's polyfill library (https://github.com/Yaffle/EventSource), and that works ok, but I'd very much like to use this library since it has custom header support.

I've tried to produce as minimal a repro as I can below. I also made a repo which you can clone and run that way to make it easier: https://github.com/esalter/eventsource-safari

Thanks so much in advance! I appreciate it.

app.js:

var app = require('express')();
var cors = require('cors');
app.use(cors());

app.get('/stream', function(req, res) {
        req.socket.setTimeout(20000);
    res.writeHead(200, {
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive'
var app = require('express')();
var cors = require('cors');
app.use(cors());

app.get('/stream', function(req, res) {
	req.socket.setTimeout(20000);
	res.writeHead(200, {
		'Content-Type': 'text/event-stream',
		'Cache-Control': 'no-cache',
 		'Connection': 'keep-alive'
	});
	res.write('\n');

	setInterval(function(){
		var msg = Math.random();
		res.write("data: "+ msg + "\n\n"); // <- Push a message to a single attached client
	}, 2000);
});

app.listen(8080);

src.js:

let EventSourceNpm = require('eventsource');
var sourceNative = new EventSource("http://localhost:8080/stream");
var sourceNpm = new EventSourceNpm("http://localhost:8080/stream");
sourceNative.onmessage = function(e) {
	console.log("from REAL eventsource", e);
};
sourceNpm.onmessage = function(e) {
	console.log("from npm eventsource", e);
};

index.html:

<!DOCTYPE html> <html> <body>
<script type="text/javascript" src="bundle.js" ></script>
</body> </html>

package.json:

{
  "name": "sse-server",
  "version": "0.0.1",
  "main": "app.js",
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "cors": "^2.8.1",
    "eventsource": "^0.2.2",
    "express": "^4.15.2",
    "webpack": "^2.2.1"
  }
}

Run with:

npm install
./node_modules/.bin/webpack ./src.js bundle.js
npm start

Then open index.html in safari and view the developer console. In safari only messages from the native EventSource library will be shown. Chrome shows both. If you kill the server, Safari will receive all messages all at once.

Messages are delayed in IE 11

Hi, I'm trying to use this library with IE 11 but I get a weird behaviour: the messages are delayed and they are received by the client all at once after a certain period of time (around 2 minutes!). To test this I have a simple server in Express that emits messages every 2 secs.

In my express server, the headers I set are these:

// set timeout as high as possible
req.socket.setTimeout(0);

// send headers for event-stream connection
// see spec for more information
resp.writeHead(200, {
	'Content-Type': 'text/event-stream',
	'Cache-Control': 'no-cache',
	'Connection': 'keep-alive',
	'Access-Control-Allow-Origin': '*'
});
resp.write('\n');

The messages are created like this:

var d = new Date();
resp.write('id: ' + d.getMilliseconds() + '\n');
resp.write('event:' + 'message') + '\n');
resp.write('data:' + createMsg(d) + '\n\n'); // Note the extra newline

Finally, in the client I use it as suggested:

let eventSource = new EventSource("http://localhost:4000/sse");
eventSource.addEventListener("message", (event) => console.log("message received:", event), false);
eventSource.addEventListener("open", (event) => console.log("onopen:", event), false);
eventSource.addEventListener("error", (event) => console.log("onerror:", event), false);

As I said, the messages are delayed in IE 11 and they arrive all together after 2 mins aprox.

However, if I use this other EventSource polyfill which is a fork of Yaffle/EventSource, IE11 receives the messages immediately as soon as the server sends them.

I'm wondering if your polyfill is supposed to work in IE11 or is not supported? If it is supported, do you happen to know what the issue could be?

Graceful handling of parse errors

If a server sends data that can't be parsed, the parser throws an Error that isn't caught. It should be caught and the onerror event handler should be fired. This is related to #18, but even if that is fixed we still need to handle parse errors since there is no guarantee that a server will send valid data.

Add support for "retry"

If the field value consists of only ASCII digits, then interpret the field value as an integer in base ten, and set the event stream's reconnection time to that integer. Otherwise, ignore the field.
-W3 Specs

Edit: Looked through the code again and saw that it was already implemented, missed it the first time. Sorry. Thanks for this awesome lib.

possible incompatibility of export with Babel

I've got a Node project that's written in ES6 and uses Babel and Rollup. There's normally no problem in using imports from CommonJS packages (i.e. basically all Node packages). However, I found that when I did something like this--

import * as EventSource from 'eventsource';

const es = EventSource(url);

--it complained that "EventSource is not a constructor". So I added a try/catch and some debug output to see what it thinks EventSource is. And it turned out to be an ordinary object, with the properties OPEN, CLOSED, and CONNECTING. In other words, it had the same properties that the EventSource export should have, but it should have been a function too and it wasn't.

What I think is going on is that the Babel logic for translating CJS exports to ES6 imports is getting confused. When it sees that module.exports was set to something that looks like an object (i.e. has properties), it thinks that those are named exports. And whatever it does to handle those involves at some point copying the properties over into a new object, which would not make any difference if the original object had been just an object, but in this case it breaks everything. If I'm correct, that means it would have the same problem with any CJS module that had a default export that was a function with properties, but I think that is a pretty rare case.

What I ended up doing was to change the code in my fork to use a single named export instead:

module.exports = {
  EventSource: EventSource
};

That works fine— it treats it as a regular named export and doesn't transform the value of EventSource at all.

I don't know if this is sufficient reason to consider making a similar export change in eventsource (which would of course be a breaking change), but I just wanted to mention it in case anyone else has run into something similar.

Support Accept-Encoding: gzip

Streaming text data (Event-source) is a perfect candidate for gzip. It would be awesome if this module supported gzip.

It can be enabled by default safely:

  • Announce gzip support with the Accept-Encoding header
  • Only decompress the response if the server responds with Content-Encoding: gzip

See https://stackoverflow.com/a/14739453/977939.

Incomplete message parsing

I have a message body where the last couple of characters are being cut off. Our application using this library sees a Parse Error and the message is lost.

We are using v1.0.5 along with the C# Service Stack Server-Events library to send messages to this. The message we are sending is below:

id: 51
data: ProjectionChannel@OrderUpdated {"id":"55bf136a15e9415985aed687b5a13cdb","streamRevision":41}

Here is what is being parsed by the EventSource node library:

id: 51
data: ProjectionChannel@OrderUpdated {"id":"55bf136a15e9415985aed687b5a13cdb","streamRevision":4

This does not happen all the time, but it does happen frequently. Have any others seen this issue?

'onmessage' not triggering in node.js

I suppose this library is meant to be used like EventSource browser interface in the nodejs, so that we could register EventSource.onmessage, EventSource.onerror and EventSource.onopen. So whenever there is a new event, the callback registered with EventSource.onmessage is triggered.
But its not working like that because of the following reason:

L185-190, the actual event type sent by the server sent event (sse) is being emitted, not the message type (which will trigger the onmessage callback), as the eventName is being set to the event name which we go from event stream.
To make it work as expected, the following lines should be changed to :

_emit('message', new MessageEvent(type, {
          data: data.slice(0, -1), // remove trailing newline
          lastEventId: lastEventId,
          origin: original(url)
})); 

If it is not expected to work like EventSource in browsers, please close the issue.

Looking for new maintainer

I don't have bandwidth to maintain this project anymore I'm afraid.

Does anyone want to take it over?

High CPU usage

Using node 0.8.x on 64bit Ubuntu 12.04, both client and server (located on same machine) spin between events, consuming high amounts of CPU. Issue does not occur on 32 bit Ubuntu with same code.

I'm able to work around this issue in eventsource.js by setting options.agent to an http.Agent with maxSockets = 1. Setting options.agent = false does not help. I'd like to understand -- is this a bug in http.Agent?

Module not found: Error: Can't resolve 'http' in node_modules/eventsource/lib

Hi,

I am running an Angular 5 with launch darkly feature flagging service which requires us to add the eventsource polyfill.
I am trying to upgrade to Angular 6 and I am running into this error on event source:

ERROR in ./node_modules/eventsource/lib/eventsource.js
Module not found: Error: Can't resolve 'http' in '/Users/mattileblanc/www/prospa/3p-e2e-app/e2e-app/node_modules/eventsource/lib'
ERROR in ./node_modules/eventsource/lib/eventsource.js
Module not found: Error: Can't resolve 'https' in '/Users/mattileblanc/www/prospa/3p-e2e-app/e2e-app/node_modules/eventsource/lib'

I am not really sure what to do with this one, is it happening because I upgrade my typescript?

My package file

{
  "name": "app",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build --prod",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "test-single-headless": "ng test --single-run=true --browsers=PhantomJS --reporters=progress,junit --code-coverage"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^6.0.0",
    "@angular/cdk": "^6.0.0",
    "@angular/common": "^6.0.0",
    "@angular/compiler": "^6.0.0",
    "@angular/core": "^6.0.0",
    "@angular/flex-layout": "^6.0.0-beta.15",
    "@angular/forms": "^6.0.0",
    "@angular/http": "^6.0.0",
    "@angular/platform-browser": "^6.0.0",
    "@angular/platform-browser-dynamic": "^6.0.0",
    "@angular/router": "^6.0.0",
    "@aspnet/signalr": "^1.0.0-preview1-update1",
    "@aspnet/signalr-client": "^1.0.0-alpha2-final",
    "@markpieszak/ng-application-insights": "^5.0.0",
    "@ngrx/entity": "^5.2.0",
    "@ngrx/store": "^5.2.0",
    "angular2-uuid": "^1.1.1",
    "classlist.js": "^1.1.20150312",
    "core-js": "^2.5.4",
    "eventsource": "^1.0.5",
    "lodash": "^4.17.4",
    "rupture": "^0.7.1",
    "rxjs": "^6.1.0",
    "rxjs-compat": "^6.1.0",
    "web-animations-js": "^2.3.1",
    "zone.js": "0.8.26"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.6.0",
    "@angular-devkit/core": "0.0.28",
    "@angular/cli": "^6.0.0",
    "@angular/compiler-cli": "^6.0.0",
    "@angular/language-service": "^6.0.0",
    "@ngrx/store-devtools": "^5.2.0",
    "@types/jasmine": "~2.8.3",
    "@types/jasminewd2": "~2.0.2",
    "@types/karma": "^1.7.3",
    "@types/node": "~8.9.4",
    "codelyzer": "^4.0.1",
    "jasmine-core": "~2.99.1",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~2.0.0",
    "karma-chrome-launcher": "~2.2.0",
    "karma-cli": "~1.0.1",
    "karma-coverage-istanbul-reporter": "^1.2.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "karma-junit-reporter": "^1.2.0",
    "karma-phantomjs-launcher": "^1.0.4",
    "phantomjs-prebuilt": "^2.1.16",
    "protractor": "~5.1.2",
    "reflect-metadata": "^0.1.12",
    "ts-node": "^6.0.3",
    "tslint": "~5.9.1",
    "typescript": "^2.7.2"
  }
}

No connection closed event when stopping Tomcat app

We are having an issue with the following setup:

  • We have a server application that uses Spring's implementation of SSE. This app is deployed on a Tomcat 8.5 server, say on http://localhost:8080/myapp. The 'register' method on this app creates the SseEmitter like this:
    SseEmitter sseEmitter = new SseEmitter(Long.valueOf(this.TIMEOUT)); SseEventBuilder sseEventBuilder = SseEmitter.event(); sseEventBuilder.reconnectTime(30000); sseEmitter.send(sseEventBuilder);

  • We have a client application that uses the eventsource-polyfill.js example. the EventSource object is initialized with an endpoint of the server app url and the corresponding open, message and error handlers:

      var emitterUrl = 'http://localhost:8080/myapp/register';
      this.eventSource=new EventSource(emitterUrl,{withCredentials: true});
      //set up EventHandlers
      this.eventSource.onopen =this.openHandler;
      this.eventSource.onmessage =this.messageHandler;
      this.eventSource.onerror =this.errorHandler;
      //set up listeners
      let list = (event && this.listeners[event.type]) || [];
      list.forEach(listener =>this.eventSource.addEventListener(type,event));
    

The following test behaves as expected:

  1. We start Tomcat and start our app
  2. We access our client app which, on startup, initializes the EventSource object
  3. We shutdown Tomcat completely
    Result: the "onConnectionClosed" method is called which calls the error handler method on our client app with the following event:

currentTarget: EventSource
onerror:f()
onmessage:ƒ ()
onopen:ƒ ()
readyState:0
url:"http://localhost:8080/myapp/register"
withCredentials:true
proto:EventSource
defaultPrevented:false
eventPhase:2
isTrusted:true

path:[]
returnValue:true
srcElement: EventSource {url: "http://localhost:8080/myapp/register", withCredentials: true, readyState: 0, onopen: ƒ, onmessage: ƒ, …}
target:EventSource {url: "http://localhost:8080/myapp/register", withCredentials: true, readyState: 0, onopen: ƒ, onmessage: ƒ, …}
type:"error"

But in this case we don't get the expected behaviour:

  1. We start Tomcat and start our app
  2. We access our client app which, on startup, initializes the EventSource object
  3. We stop our server app but the tomcat server remains started
    Result: On our client app, the error handler method is never called, so it thinks the connection is still active. We believe EventSource should fire an error event in this case.

Tested on eventsource-polyfill.js versions: 1.0.4, 0.2.1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.