Oak provides built-in support for Server-Sent Events (SSE), a one-way communication protocol. To use SSE, call ctx.sendEvents() within a route handler to establish a connection and obtain a ServerSentEventTarget.
Basic Usage
import { Application, Router } from "https://deno.land/x/oak/mod.ts";
const app = new Application();
const router = new Router();
router.get("/sse", async (ctx) => {
const target = await ctx.sendEvents();
target.dispatchMessage({ hello: "world" });
});
app.use(router.routes());
await app.listen({ port: 80 });
Handling Connection Close
You can detect when the client closes the connection by listening for the close event on the target:
router.get("/sse", async (ctx) => {
const target = await ctx.sendEvents();
target.addEventListener("close", (evt) => {
// perform cleanup activities
});
target.dispatchMessage({ hello: "world" });
});
Closing the Connection from Server
To close the connection from the server side, await the close() method on the target:
router.get("/sse", async (ctx) => {
const target = await ctx.sendEvents();
target.dispatchMessage({ hello: "world" });
await target.close();
});
Sending Custom Events
Use ServerSentEvent to send named events. These are dispatched as MessageEvent on the client side.
router.get("/sse", async (ctx: Context) => {
const target = await ctx.sendEvents();
const event = new ServerSentEvent("ping", { hello: "world" });
target.dispatchEvent(event);
});
On the client side:
const source = new EventSource("/sse");
source.addEventListener("ping", (evt) => {
console.log(evt.data); // logs string: '{"hello":"world"}'
});
Dispatching Messages and Comments
target.dispatchMessage(data): Sends a data-only message. The client receives this via source.onmessage with type "message".target.dispatchComment(comment): Sends a comment to the client. This does not trigger an event on the client but can be used for debugging or keeping the connection alive.
Cancellable Events
Events dispatched on the server can be cancelled before being sent to the client. If an event listener calls .preventDefault() on the event, the event will not be sent to the client.
Sources: docs/sse.md