diff options
| author | Joel Klinghed <the_jk@opera.com> | 2024-12-19 12:13:38 +0100 |
|---|---|---|
| committer | Joel Klinghed <the_jk@opera.com> | 2024-12-19 12:13:38 +0100 |
| commit | ddf6ec97c6ff98d0f82eff0e203a4496b6c7e4c3 (patch) | |
| tree | efc6996cc7739a6a4e19829c9908f75b4ca58ed2 | |
| parent | c2adda96c8e45af90331a4b112ed179ec8051c48 (diff) | |
clicks: Automatically close socket after 10m of no events
Useful for people that doesn't close their tab
| -rw-r--r-- | src/clicks.ts | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/src/clicks.ts b/src/clicks.ts index 620d845..096c7c6 100644 --- a/src/clicks.ts +++ b/src/clicks.ts @@ -3,6 +3,7 @@ interface ClicksWindow extends Window { } const CLICKS_WSURL: string | undefined = (<ClicksWindow>window).clicksWsUrl +const IDLE_TIMEOUT = 10 * 60 * 1000 class Session { private wss: WebSocketStream @@ -10,6 +11,9 @@ class Session { private writer: WritableStreamDefaultWriter | undefined private url: string | undefined private header: string | undefined + private sentHeader = false + private lastEvent = 0 + private timeoutInterval: number | undefined constructor(url: string, header: string) { this.wss = new WebSocketStream(url) @@ -17,8 +21,16 @@ class Session { } async connect() { + if (this.timeoutInterval === undefined) { + this.timeoutInterval = setInterval( + this.checkIdle.bind(this), + IDLE_TIMEOUT + ) + } + const openInfo = await this.wss.opened this.writer = openInfo.writable.getWriter() + this.lastEvent = Date.now() for (const event of this.queue) { void this.writer.write(event) } @@ -29,9 +41,9 @@ class Session { // but then we would report all navigations, // even if there are no clicks, which is unnecessary. if (window.location.href !== this.url) { - if (this.header !== undefined) { + if (!this.sentHeader && this.header !== undefined) { this.pushEvent(this.header) - this.header = undefined + this.sentHeader = true } this.url = window.location.href this.pushEvent(`u|${this.url}`) @@ -43,10 +55,35 @@ class Session { private pushEvent(event: string) { if (this.writer === undefined) { this.queue.push(event) + + if (this.timeoutInterval === undefined) { + void this.connect() + } } else { + this.lastEvent = Date.now() + void this.writer.write(event) } } + + private checkIdle() { + if (Date.now() - this.lastEvent >= IDLE_TIMEOUT) { + this.closeOnIdle() + } + } + + private closeOnIdle() { + if (this.timeoutInterval !== undefined) { + clearInterval(this.timeoutInterval) + this.timeoutInterval = undefined + } + this.writer = undefined + const url = this.wss.url + this.wss.close() + this.wss = new WebSocketStream(url) + this.sentHeader = false + this.url = undefined + } } function startSession(data: string): Session | undefined { |
