Skip to content

Instantly share code, notes, and snippets.

@callionica
Created June 17, 2022 09:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save callionica/238d229402033dd08fad6634ebe15133 to your computer and use it in GitHub Desktop.
Save callionica/238d229402033dd08fad6634ebe15133 to your computer and use it in GitHub Desktop.
// Server-Sent Events
type RequestEvent = Deno.RequestEvent;
type Connection = Deno.Conn;
type StreamController = ReadableStreamDefaultController<Uint8Array>;
const encoder = new TextEncoder();
export class EventConnection {
request: RequestEvent;
controller: StreamController | undefined;
constructor(request: RequestEvent) {
this.request = request;
}
write(text: string) {
try {
if (this.controller === undefined) {
console.log("dropped write", text);
return;
}
this.controller.enqueue(encoder.encode(text));
} catch (e) {
// TODO
console.log(e);
throw e;
}
}
connect_(controller: StreamController) {
console.log("connect_");
this.controller = controller;
}
cancel_(reason: string) {
console.log("cancel_");
}
async connect() {
const self = this;
const body = new ReadableStream<Uint8Array>({
start: (controller) => {
self.connect_(controller);
},
// pull(controller) {
// console.log("PULL");
// },
cancel: (reason) => {
self.cancel_(reason);
}
});
const headers = {
"Connection": "keep-alive",
"Cache-control": "no-cache",
"Content-type": "text/event-stream",
"Keep-Alive": `timeout=${Number.MAX_SAFE_INTEGER}`
};
const response = new Response(body, { headers, status: 200, statusText: "OK" });
await this.request.respondWith(Promise.resolve(response));
}
async sendMessage(
data: string | object,
eventName?: string | undefined,
id?: string | undefined
) {
const text = (typeof data === "string") ? data : JSON.stringify(data, null, 2);
if (eventName !== undefined) {
this.write(`event: ${eventName}\n`);
}
if (id !== undefined) {
this.write(`id: ${eventName}\n`);
}
this.write("data: ");
this.write(text.replaceAll("\n", "\ndata: ")); // TODO - efficiency
this.write("\n\n");
}
}
@callionica
Copy link
Author

const ec = new EventConnection(requestEvent);
ec.connect();

ec.sendMessage("any data");

@callionica
Copy link
Author

In the browser:
const source = new EventSource('');
source.addEventListener('message', function(e) {
console.log(e.data);
}, false);

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