-
Notifications
You must be signed in to change notification settings - Fork 105
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(events): create server event emitter
This commit adds the class `Topic`, a redis-based event emitter permitting controllers to subscribe/unsubscribe from channels and react to events on those channels. Redis is already an installation requirement for the application, so this adds minimal dependency overhead. The basic usage looks like this: ```js // import Topic const Topic = require('topic'); Topic.subscribe('channelName', (data) => console.log(data)); Topic.publish('channelName, { key : 'value' }); Topic.unsubscribe('channelName'); ``` Closes #390.
- Loading branch information
Showing
8 changed files
with
505 additions
and
128 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/** | ||
* @overview | ||
* This controller uses the topic library to broadcast events to the client | ||
* along a server-sent events channel. It includes two channels: | ||
* 1. `/stream` for real-time event broadcasts. | ||
* 2. `/events` for listing all events in the last day | ||
* | ||
* @requires lib/db | ||
* @requires lib/topic | ||
*/ | ||
|
||
'use strict'; | ||
|
||
const db = require('../lib/db'); | ||
const topic = require('../lib/topic'); | ||
|
||
// GET /stream | ||
exports.stream = stream; | ||
|
||
// GET /events | ||
exports.list = list; | ||
|
||
// event stream to be set to the client | ||
function stream(req, res) { | ||
|
||
// ensure the socket hangs open forever | ||
res.set('Content-Type', 'text/event-stream'); | ||
res.set('Content-Control', 'no-cache'); | ||
|
||
// this listener publishes events to the client as server-sent events | ||
function listener(data) { | ||
res.write(`data: ${JSON.stringify(data)}\n\n`).flush(); | ||
} | ||
|
||
// listen for server events and echo them to the client | ||
topic.subscribe(topic.channels.ALL, listener); | ||
|
||
// remove listener on when the client closes the connection | ||
res.on('close', () => topic.unsubscribe(topic.channels.ALL, listener)); | ||
} | ||
|
||
// list the events in the database | ||
function list(req, res, next) { | ||
let sql = ` | ||
SELECT event.data FROM event LIMIT 500; | ||
`; | ||
|
||
db.exec(sql) | ||
.then(rows => { | ||
let events = rows.map(row => JSON.parse(row.data)); | ||
res.status(200).json(events); | ||
}) | ||
.catch(next) | ||
.done(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.