Skip to content

Instantly share code, notes, and snippets.

@sperand-io
Last active September 7, 2020 12:09
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sperand-io/7688d388a895e37fe4bb to your computer and use it in GitHub Desktop.
Save sperand-io/7688d388a895e37fe4bb to your computer and use it in GitHub Desktop.
Koa EventSource Streaming (SSE)
const PassThrough = require('stream').PassThrough;
const Router = require('koa-66');
const router = new Router();
const Koa = require('koa');
const app = new Koa();
// ...
const sse = (event, data) => {
return `event:${ event }\ndata: ${ data }\n\n`
}
router.get(`/json/data/:source`, ctx => {
const stream = new PassThrough();
const { source } = ctx.params;
const { db } = app.context; // or whatever :)
const reader = db.createReader(source); // or whatever :)
const send = (data) => {
let { type, msg } = data; // or whatever :)
stream.write(sse(type, msg));
}
reader.on('data', send);
ctx.req.on('close', () => ctx.res.end());
ctx.req.on('finish', () => ctx.res.end());
ctx.req.on('error', () => ctx.res.end());
ctx.type = 'text/event-stream';
ctx.body = stream;
});
app.use(router.routes());
app.listen(3000);
@sclark39
Copy link

This doesn't seem to work. I get an error with it "listener" argument must be a function, on line 20.

@Francois-Esquire
Copy link

Francois-Esquire commented Dec 1, 2017

@sclark39, sse() needs to be a function declaration to work from where it's placed. Otherwise, try:

...
const sse = (event, data) => {
  return `event:${ event }\ndata: ${ data }\n\n`
}

router.get(`/json/data/:source`, ctx => { ... });

Defining sse() before it's called should fix the problem.

@unek
Copy link

unek commented Jan 5, 2020

  ctx.req.on('close', () => ctx.res.end());
  ctx.req.on('finish', () => ctx.res.end());
  ctx.req.on('error', () => ctx.res.end());

fixes the issue @sclark39 mentioned

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment