From 740b59f3892d84e7a37d3abcb185b0b7e16044e0 Mon Sep 17 00:00:00 2001 From: m5r Date: Mon, 27 Jun 2022 14:03:49 +0200 Subject: [PATCH] keep SSE connection alive --- app/routes/__app/sse.notifications.ts | 40 +++++++++++++++++---------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/app/routes/__app/sse.notifications.ts b/app/routes/__app/sse.notifications.ts index 6f1c3d2..3bb1d65 100644 --- a/app/routes/__app/sse.notifications.ts +++ b/app/routes/__app/sse.notifications.ts @@ -12,21 +12,8 @@ export let loader: LoaderFunction = ({ request }) => { new ReadableStream({ start(controller) { const encoder = new TextEncoder(); - const onNotification = (notification: NotificationPayload) => { - controller.enqueue(encoder.encode(`data: ${JSON.stringify(notification)}\n\n`)); - }; - + let keepAliveTimeout = setTimeout(keepAlive, 30 * 1000); let closed = false; - function close() { - if (closed) { - return; - } - - closed = true; - events.removeListener("notification", onNotification); - request.signal.removeEventListener("abort", close); - controller.close(); - } events.addListener("notification", onNotification); request.signal.addEventListener("abort", close); @@ -34,6 +21,31 @@ export let loader: LoaderFunction = ({ request }) => { close(); return; } + + function onNotification(notification: NotificationPayload) { + controller.enqueue(encoder.encode(`data: ${JSON.stringify(notification)}\n\n`)); + } + + function keepAlive() { + if (closed) { + return; + } + + controller.enqueue(encoder.encode(":\n\n")); + keepAliveTimeout = setTimeout(keepAlive, 30 * 1000); + } + + function close() { + if (closed) { + return; + } + + closed = true; + clearTimeout(keepAliveTimeout); + events.removeListener("notification", onNotification); + request.signal.removeEventListener("abort", close); + controller.close(); + } }, }), {