mirror of
https://github.com/sr229/kuru-kuru.git
synced 2024-09-20 04:10:33 +00:00
Switch transport to Websockets
This commit is contained in:
parent
33c03ca078
commit
4ea19cd5a0
4 changed files with 53 additions and 76 deletions
|
@ -4,8 +4,7 @@
|
||||||
|
|
||||||
import * as $0 from "./routes/_404.tsx";
|
import * as $0 from "./routes/_404.tsx";
|
||||||
import * as $1 from "./routes/_app.tsx";
|
import * as $1 from "./routes/_app.tsx";
|
||||||
import * as $2 from "./routes/_middleware.ts";
|
import * as $2 from "./routes/index.tsx";
|
||||||
import * as $3 from "./routes/index.tsx";
|
|
||||||
import * as $$0 from "./islands/CounterCard.tsx";
|
import * as $$0 from "./islands/CounterCard.tsx";
|
||||||
import * as $$1 from "./islands/MarkdownContent.tsx";
|
import * as $$1 from "./islands/MarkdownContent.tsx";
|
||||||
|
|
||||||
|
@ -13,8 +12,7 @@ const manifest = {
|
||||||
routes: {
|
routes: {
|
||||||
"./routes/_404.tsx": $0,
|
"./routes/_404.tsx": $0,
|
||||||
"./routes/_app.tsx": $1,
|
"./routes/_app.tsx": $1,
|
||||||
"./routes/_middleware.ts": $2,
|
"./routes/index.tsx": $2,
|
||||||
"./routes/index.tsx": $3,
|
|
||||||
},
|
},
|
||||||
islands: {
|
islands: {
|
||||||
"./islands/CounterCard.tsx": $$0,
|
"./islands/CounterCard.tsx": $$0,
|
||||||
|
|
|
@ -89,7 +89,7 @@ export default function Counter(props: SharedProps) {
|
||||||
JSON.stringify({ data: internalCount + 1 }),
|
JSON.stringify({ data: internalCount + 1 }),
|
||||||
);
|
);
|
||||||
console.info(
|
console.info(
|
||||||
`[${new Date()}] Updating global count: ${internalCount + 1}`,
|
`[${new Date().toISOString()}] Updating global count: ${internalCount + 1}`,
|
||||||
);
|
);
|
||||||
setInternalCount(0);
|
setInternalCount(0);
|
||||||
}
|
}
|
||||||
|
@ -97,27 +97,26 @@ export default function Counter(props: SharedProps) {
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let es = new EventSource(window.location.href);
|
let ws = new WebSocket(window.location.href.replace("http", "ws"));
|
||||||
|
|
||||||
es.addEventListener("open", () => {
|
ws.addEventListener("open", () => {
|
||||||
console.log(`[${new Date()}] Connected to statistics stream`);
|
console.log(`[${new Date().toISOString()}] Connected to statistics socket`);
|
||||||
});
|
});
|
||||||
|
|
||||||
es.addEventListener("message", (e) => {
|
ws.addEventListener("message", (e) => {
|
||||||
console.log(`[${new Date()}] Received global count: ${e.data}`);
|
console.log(`[${new Date().toISOString()}] Received global count: ${e.data}`);
|
||||||
const data = JSON.parse(e.data);
|
const data = JSON.parse(e.data);
|
||||||
setGlobalCount(BigInt(parseInt(data.globalCount)));
|
setGlobalCount(BigInt(parseInt(data.globalCount)));
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: Reconnect backoff logic could be improved
|
ws.addEventListener("error", () => {
|
||||||
es.addEventListener("error", () => {
|
|
||||||
console.warn(
|
console.warn(
|
||||||
`[${new Date()}] Disconnected from statistics stream, attempting to reconnect...`,
|
`[${new Date().toISOString()}] Disconnected from statistics socket, attempting to reconnect...`,
|
||||||
);
|
);
|
||||||
const backoff = 1000 + Math.random() * 5000;
|
const backoff = 1000 + Math.random() * 5000;
|
||||||
new Promise((resolve) => setTimeout(resolve, backoff));
|
new Promise((resolve) => setTimeout(resolve, backoff));
|
||||||
es = new EventSource(window.location.href);
|
ws = new WebSocket(window.location.href.replace("http", "ws"));
|
||||||
});
|
})
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
import { MiddlewareHandlerContext } from "$fresh/server.ts";
|
|
||||||
|
|
||||||
export async function handler(req: Request, ctx: MiddlewareHandlerContext) {
|
|
||||||
const origin = req.headers.get("Origin") || "*";
|
|
||||||
const resp = await ctx.next();
|
|
||||||
const headers = resp.headers;
|
|
||||||
|
|
||||||
headers.set("Access-Control-Allow-Origin", origin);
|
|
||||||
headers.set("Access-Control-Allow-Credentials", "true");
|
|
||||||
headers.set("X-Content-Type-Options", "nosniff");
|
|
||||||
headers.set("Cache-Control", "public, max-age=3600");
|
|
||||||
headers.set(
|
|
||||||
"Access-Control-Allow-Headers",
|
|
||||||
"Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, accept, origin, Cache-Control, X-Requested-With",
|
|
||||||
);
|
|
||||||
headers.set(
|
|
||||||
"Access-Control-Allow-Methods",
|
|
||||||
"POST, OPTIONS, GET",
|
|
||||||
);
|
|
||||||
|
|
||||||
return resp;
|
|
||||||
}
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { Handlers } from "$fresh/server.ts";
|
import { Handlers } from "$fresh/server.ts";
|
||||||
import Counter from "../islands/CounterCard.tsx";
|
import Counter from "../islands/CounterCard.tsx";
|
||||||
import { CSS, render } from "$gfm";
|
|
||||||
import { getGlobalStatistics, setGlobalStatistics } from "../shared/db.ts";
|
import { getGlobalStatistics, setGlobalStatistics } from "../shared/db.ts";
|
||||||
import MarkdownContent from "../islands/MarkdownContent.tsx";
|
import MarkdownContent from "../islands/MarkdownContent.tsx";
|
||||||
|
|
||||||
|
@ -19,46 +18,46 @@ for (const f of Deno.readDirSync("static/assets/audio/ja/")) {
|
||||||
|
|
||||||
export const handler: Handlers = {
|
export const handler: Handlers = {
|
||||||
GET: async (req, ctx) => {
|
GET: async (req, ctx) => {
|
||||||
const accept = req.headers.get("accept");
|
let bc = new BroadcastChannel("global-count");
|
||||||
|
|
||||||
if (accept?.includes("text/event-stream")) {
|
// check if we're requesting wss:// or ws://, add the response header accordingly
|
||||||
const bc = new BroadcastChannel("global-count");
|
if (req.headers.get("upgrade") === "websocket") {
|
||||||
const body = new ReadableStream({
|
const { socket, response } = Deno.upgradeWebSocket(req);
|
||||||
start(controller) {
|
|
||||||
bc.addEventListener("message", async () => {
|
socket.onopen = () => {
|
||||||
try {
|
bc = new BroadcastChannel("global-count");
|
||||||
const data = await getGlobalStatistics();
|
console.log(
|
||||||
const chunk = `data: ${
|
`[${new Date().toISOString()}] Connection opened for ${
|
||||||
JSON.stringify({ globalCount: data })
|
JSON.stringify(ctx.remoteAddr)
|
||||||
}\n\n`;
|
}`,
|
||||||
controller.enqueue(new TextEncoder().encode(chunk));
|
);
|
||||||
} catch (e) {
|
};
|
||||||
console.error(
|
|
||||||
`[${new Date()}] Error while getting global statistics: ${e}`,
|
bc.addEventListener("message", (e) => {
|
||||||
);
|
socket.send(JSON.stringify({ globalCount: e.data }));
|
||||||
}
|
|
||||||
});
|
|
||||||
console.log(
|
|
||||||
`[${new Date()}] Opened statistics stream for ${
|
|
||||||
JSON.stringify(ctx.remoteAddr)
|
|
||||||
}`,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
cancel() {
|
|
||||||
bc.close();
|
|
||||||
console.log(
|
|
||||||
`[${new Date()}] Closed statistics stream for ${
|
|
||||||
JSON.stringify(ctx.remoteAddr)
|
|
||||||
}`,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return new Response(body, {
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "text/event-stream; charset=utf-8",
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
socket.onclose = () => {
|
||||||
|
bc.close();
|
||||||
|
console.log(
|
||||||
|
`[${new Date().toISOString()}] Connection closed for ${
|
||||||
|
JSON.stringify(ctx.remoteAddr)
|
||||||
|
}`,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.onerror = (e) => {
|
||||||
|
bc.close();
|
||||||
|
console.error(
|
||||||
|
`[${new Date().toISOString()}] Connection errored for ${
|
||||||
|
JSON.stringify(ctx.remoteAddr)
|
||||||
|
}: ${e}`,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await getGlobalStatistics();
|
const data = await getGlobalStatistics();
|
||||||
const res = await ctx.render({ globalCount: data });
|
const res = await ctx.render({ globalCount: data });
|
||||||
return res;
|
return res;
|
||||||
|
@ -84,7 +83,10 @@ export default function Home(
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div class="px-4 py-8 mx-auto bg-[#9d88d3]">
|
<div class="px-4 py-8 mx-auto bg-[#9d88d3]">
|
||||||
<div class="max-w-screen-md mx-auto flex flex-col items-center justify-center" id="mascot-tgt">
|
<div
|
||||||
|
class="max-w-screen-md mx-auto flex flex-col items-center justify-center"
|
||||||
|
id="mascot-tgt"
|
||||||
|
>
|
||||||
<img class="z-10" src="/favicon.png" width="60px" />
|
<img class="z-10" src="/favicon.png" width="60px" />
|
||||||
<h1 class="text-4xl text-white text-center font-bold z-10">
|
<h1 class="text-4xl text-white text-center font-bold z-10">
|
||||||
Welcome to herta kuru
|
Welcome to herta kuru
|
||||||
|
|
Loading…
Reference in a new issue