summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Klinghed <the_jk@opera.com>2024-12-19 12:13:38 +0100
committerJoel Klinghed <the_jk@opera.com>2024-12-19 12:13:38 +0100
commitddf6ec97c6ff98d0f82eff0e203a4496b6c7e4c3 (patch)
treeefc6996cc7739a6a4e19829c9908f75b4ca58ed2
parentc2adda96c8e45af90331a4b112ed179ec8051c48 (diff)
clicks: Automatically close socket after 10m of no events
Useful for people that doesn't close their tab
-rw-r--r--src/clicks.ts41
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 {