Skip to content

Instantly share code, notes, and snippets.

@laat
Last active February 9, 2022 09:40
Show Gist options
  • Save laat/a2ee91fbe2effc54e49467cd88636a0d to your computer and use it in GitHub Desktop.
Save laat/a2ee91fbe2effc54e49467cd88636a0d to your computer and use it in GitHub Desktop.
Server-Sent Events over HTTP/2 on Node.JS
Relays messages published on a redis channel over Server-Sent Events.
import redis from 'redis';
import { readFileSync } from 'node:fs';
import { createSecureServer } from 'node:http2';
import EventEmitter from 'node:events';
const server = createSecureServer(
{
key: readFileSync('localhost-key.pem'),
cert: readFileSync('localhost.pem'),
allowHTTP1: true
},
(req, res) => {
if (req.httpVersionMajor !== 2) {
res.statusCode = 400;
res.end("HTTP/2 only");
}
}
);
server.on('error', (err) => console.error(err));
const sseMessage = Symbol('SSE Message');
const sseEvents = new EventEmitter();
const client = redis.createClient({ url: 'redis://localhost:6379' });
await client.connect();
await client.subscribe('chat', (message) => {
sseEvents.emit(sseMessage, message);
});
server.on('stream', (stream, headers) => {
if (headers[':path'] !== '/sse') return;
if (headers[':method'] !== 'GET') return;
stream.respond({
':status': 200,
'content-type': 'text/event-stream',
'cache-control': 'no-cache',
});
const onMessage = (message: string) => stream.write(`data: ${message}\n\n`);
sseEvents.on(sseMessage, onMessage);
stream.on('close', () => sseEvents.off(sseMessage, onMessage));
});
server.on("stream", (stream) => {
if (stream.headersSent) return;
stream.respond({ ":status": 404 });
stream.end("not found");
});
server.listen(8443);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment