Build a websocket topics framework

This commit is contained in:
Alex Gleason
2023-05-20 19:39:05 -05:00
parent 02160f8c9e
commit 3ffad1df29
6 changed files with 116 additions and 21 deletions

View File

@@ -1,14 +1,12 @@
import { AppController } from '@/app.ts';
import { nip19 } from '@/deps.ts';
import { TOKEN_REGEX } from '@/middleware/auth.ts';
import { signStreams } from '@/sign.ts';
import ws from '@/stream.ts';
import { bech32ToPubkey } from '@/utils.ts';
const streamingController: AppController = (c) => {
const upgrade = c.req.headers.get('upgrade');
const token = c.req.headers.get('sec-websocket-protocol');
const stream = c.req.query('stream');
const nostr = c.req.query('nostr');
if (upgrade?.toLowerCase() !== 'websocket') {
return c.text('Please use websocket protocol', 400);
@@ -18,25 +16,31 @@ const streamingController: AppController = (c) => {
return c.json({ error: 'Missing access token' }, 401);
}
if (!(new RegExp(`^${TOKEN_REGEX.source}$`)).test(token)) {
const match = token.match(new RegExp(`^${TOKEN_REGEX.source}$`));
if (!match) {
return c.json({ error: 'Invalid access token' }, 401);
}
const { socket, response } = Deno.upgradeWebSocket(c.req.raw, { protocol: token });
const conn = {
socket,
session: match[2],
pubkey: bech32ToPubkey(match[1]),
};
socket.addEventListener('open', () => {
console.log('websocket: connection opened');
// Only send signing events if the user has a session ID.
if (stream === 'user' && nostr === 'true' && new RegExp(`^${nip19.BECH32_REGEX.source}_\\w+$`).test(token)) {
signStreams.set(token, socket);
if (stream) {
ws.subscribe(conn, { name: stream });
}
});
socket.addEventListener('message', (e) => console.log('websocket message: ', e.data));
socket.addEventListener('close', () => {
signStreams.delete(token);
console.log('websocket: connection closed');
ws.unsubscribe(conn, { name: stream! });
});
return response;