-
Notifications
You must be signed in to change notification settings - Fork 0
/
ReconnectHandler.ts
67 lines (60 loc) · 2.13 KB
/
ReconnectHandler.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import { v5 } from "https://deno.land/[email protected]/uuid/mod.ts";
import { QUEUES } from "./AmqpInterface.ts";
import { amqp, amqpHandlers } from "./deps_int.ts";
import { handleFinalDisconnect } from "./server.ts";
import { removeGame } from "./serverstate.ts";
const reconnectCodesLocal = new Map<string, string>(); // Map<id, reconnectCode>
const pendingReconnectsSynced = new Map<string, string>(); // Map<id, reconnectCode>
export async function generateReconnectCode(id: string): Promise<string> {
let code = await v5.generate(
"6ba7b810-9dad-11d1-80b4-00c04fd430c8",
new TextEncoder().encode(JSON.stringify(id + Date.now() + Math.random())),
);
code = code.replaceAll("-", "");
reconnectCodesLocal.set(id, code);
return code;
}
export function verifyReconnectCode(id: string, code: string): boolean {
return pendingReconnectsSynced.get(id) === code;
}
export async function startReconnectTransaction(id: string) {
const currentCode = reconnectCodesLocal.get(id);
await amqp.publish(QUEUES.reconnect, {
id: id,
code: currentCode,
});
// Reset after 10 second timeout
setTimeout(() => {
if (pendingReconnectsSynced.get(id) === currentCode) {
amqpHandlers.handleSendGameClosedMessage(id);
removeGame(id);
handleFinalDisconnect(id);
}
}, 10_000);
}
export async function completeReconnectTransaction(
id: string,
): Promise<string> {
await amqp.publish(QUEUES.reconnectComplete, { id: id });
// Regenerate reconnect code
const newCode = await generateReconnectCode(id);
return newCode;
}
async function subscribeToReconnects() {
await amqp.subscribe(QUEUES.reconnect, (message: any) => {
pendingReconnectsSynced.set(message.id, message.code);
// Timeout reconnects after 10 seconds
setTimeout(() => {
if (pendingReconnectsSynced.get(message.id) === message.code) {
pendingReconnectsSynced.delete(message.id);
}
}, 10_000);
});
}
subscribeToReconnects();
async function subscribeToReconnectComplete() {
await amqp.subscribe(QUEUES.reconnectComplete, (message: any) => {
pendingReconnectsSynced.delete(message.id);
});
}
subscribeToReconnectComplete();