From 7fa5f15317e3b069c3118e0fbe4e80ab860ffeea Mon Sep 17 00:00:00 2001 From: Matthew Podwysocki Date: Fri, 15 Aug 2014 15:47:53 -0400 Subject: [PATCH] Adding server-sent events --- Gruntfile.js | 2 ++ bower.json | 2 +- doc/operators/fromeventsource.md | 59 ++++++++++++++++++++++++++++++++ doc/readme.md | 3 ++ package.json | 2 +- src/eventsource.js | 42 +++++++++++++++++++++++ 6 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 doc/operators/fromeventsource.md create mode 100644 src/eventsource.js diff --git a/Gruntfile.js b/Gruntfile.js index 9eeeca2..87ada7d 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -32,6 +32,7 @@ module.exports = function (grunt) { 'src/jsonp.js', 'src/websocket.js', 'src/webworker.js', + 'src/evensource.js', 'src/mutationobserver.js', 'src/requestanimationframescheduler.js', 'src/mutationobserverscheduler.js', @@ -52,6 +53,7 @@ module.exports = function (grunt) { 'src/jsonp.js', 'src/websocket.js', 'src/webworker.js', + 'src/evensource.js', 'src/mutationobserver.js', 'src/requestanimationframescheduler.js', 'src/mutationobserverscheduler.js', diff --git a/bower.json b/bower.json index 1faa5b3..51e772c 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "rxjs-dom", - "version": "4.0.0", + "version": "4.0.1", "main": "dist/rx.dom.js", "dependencies": { "rxjs": "*" diff --git a/doc/operators/fromeventsource.md b/doc/operators/fromeventsource.md new file mode 100644 index 0000000..ade30a3 --- /dev/null +++ b/doc/operators/fromeventsource.md @@ -0,0 +1,59 @@ +### `Rx.DOM.from(url, [openObserver])` +[Ⓢ](https://github.com/Reactive-Extensions/RxJS-DOM/blob/master/src/eventsource.js "View in source") + +This method wraps an EventSource as an observable sequence which is used to send server-side events. Note that your browser must support EventSource objects. + +#### Arguments +1. `url` *(String)*: The URL of the Server-Side Events. +3. `[openObserver]` *(`Rx.Observer`)*: An optional Observer to capture the open event. + +#### Returns +*(`Observable`)*: An observable sequence which represents the data from a server-side event. + +#### Example +```js +// Using a function for the open +var source = Rx.DOM.fromEventSource('foo.php'); + +source.subscribe(function (e) { + console.log('Received data: ' + e.data); +}); + + +// Using an observer for the open +var observer = Rx.Observer.create(function (e) { + console.log('Opening'); +}); + +// Using a function for the open +var source = Rx.DOM.fromEventSource('foo.php', observer); + +socket.subscribe(function (e) { + console.log('Received data: ' + e.data); +}); + +socket.onNext('data'); +``` + +### Location + +File: +- [`/src/eventsource.js`](https://github.com/Reactive-Extensions/RxJS-DOM/blob/master/src/eventsource.js) + +Dist: +- [`rx.dom.js`](https://github.com/Reactive-Extensions/RxJS-DOM/blob/master/dist/rx.dom.js) | - [`rx.dom.compat.js`](https://github.com/Reactive-Extensions/RxJS-DOM/blob/master/dist/rx.dom.compat.js) + +Prerequisites: +- If using `rx.js` + - [`rx.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.js) | [`rx.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.compat.js) + - [`rx.binding.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/dist/rx.binding.js) +- [`rx.lite.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/rx.lite.js) | [`rx.lite.compat.js`](https://github.com/Reactive-Extensions/RxJS/blob/master/rx.lite.compat.js) + +NPM Packages: +- [`rx-dom`](https://preview.npmjs.com/package/rx-dom) + +NuGet Packages: +- [`RxJS-Bridges-HTML`](http://www.nuget.org/packages/RxJS-Bridges-HTML/) + +Unit Tests: +- [`/tests/tests.eventsource.js](https://github.com/Reactive-Extensions/RxJS-DOM/blob/master/tests/tests.eventsource.js) diff --git a/doc/readme.md b/doc/readme.md index 3cde19f..08c17da 100644 --- a/doc/readme.md +++ b/doc/readme.md @@ -64,6 +64,9 @@ This section contains the reference documentation for the Reactive Extensions fo - [`Rx.DOM.post`](operators/post.md) - [`Rx.DOM.jsonpRequest`](operators/jsonprequest.md) +Server-Sent Events +- [`Rx.DOM.fromEventSource`](operators/fromeventsource.md) + Web Sockets - [`Rx.DOM.fromWebSocket`](operators/fromwebsocket.md) diff --git a/package.json b/package.json index 9eebee0..1555a37 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "rx-dom", "title": "The Reactive Extensions Bindings for the DOM.", "description": "Library for using DOM elements as well as Ajax requests", - "version": "4.0.0", + "version": "4.0.1", "homepage": "https://github.com/Reactive-Extensions/RxJS-DOM", "author": { "name": "MS Open Tech", diff --git a/src/eventsource.js b/src/eventsource.js new file mode 100644 index 0000000..656425a --- /dev/null +++ b/src/eventsource.js @@ -0,0 +1,42 @@ + if (!!root.EventSource) { + + /** + * This method wraps an EventSource as an observable sequence. + * @param {String} url The url of the server-side script. + * @param {Observer} [openObserver] An optional observer for the 'open' event for the server side event. + * @returns {Observable} An observable sequence which represents the data from a server-side event. + */ + dom.fromEventSource = function (url, openObserver) { + return new AnonymousObservable(function (observer) { + var source = new root.EventSource(url); + + function onOpen(e) { + openObserver.onNext(e); + openObserver.onCompleted(); + source.removeEventListener('open', onOpen, false); + } + + function onError(e) { + if (e.readyState === EventSource.CLOSED) { + observer.onCompleted(); + } else { + observer.onError(e); + } + } + + function onMessage(e) { + observer.onNext(e); + } + + openObserver && source.addEventListener('open', onOpen, false); + source.addEventListener('error', onError, false); + source.addEventListener('message', onMessage, false); + + return function () { + source.removeEventListener('error', onError, false); + source.removeEventListener('message', onMessage, false); + source.close(); + }; + }); + }; + }