mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-06-03 16:38:50 -04:00
feat(packages): add commons package
This is an import of 166ca8da12
with some changes to make it fit into the mono repo.
- TypedEventEmitter has been replaced with EventEmitter2 because EventEmitter2 is faster and TypedEventEmitter had some troubles with the new way of compiling.
- tsc-esm has been replaced with microbundle. The problems that lib0 doesn't export its types correctly has been solved using yarn patch.
Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
parent
814d8bc856
commit
7320fe2ac1
49 changed files with 3058 additions and 88 deletions
77
commons/src/connection-keep-alive-handler.ts
Normal file
77
commons/src/connection-keep-alive-handler.ts
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import { MessageType } from './messages/message-type.enum.js'
|
||||
import type { YDocMessageTransporter } from './y-doc-message-transporter.js'
|
||||
import { createEncoder, toUint8Array, writeVarUint } from 'lib0/encoding'
|
||||
|
||||
/**
|
||||
* Provides a keep alive ping for a given {@link WebSocket websocket} connection by sending a periodic message.
|
||||
*/
|
||||
export class ConnectionKeepAliveHandler {
|
||||
private pongReceived = false
|
||||
private static readonly pingTimeout = 30 * 1000
|
||||
private intervalId: NodeJS.Timer | undefined
|
||||
|
||||
/**
|
||||
* Constructs the instance and starts the interval.
|
||||
*
|
||||
* @param messageTransporter The websocket to keep alive
|
||||
*/
|
||||
constructor(private messageTransporter: YDocMessageTransporter) {
|
||||
this.messageTransporter.on('disconnected', () => this.stopTimer())
|
||||
this.messageTransporter.on('ready', () => this.startTimer())
|
||||
this.messageTransporter.on(String(MessageType.PING), () => {
|
||||
this.sendPongMessage()
|
||||
})
|
||||
this.messageTransporter.on(
|
||||
String(MessageType.PONG),
|
||||
() => (this.pongReceived = true)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the ping timer.
|
||||
*/
|
||||
public startTimer(): void {
|
||||
this.pongReceived = false
|
||||
this.intervalId = setInterval(
|
||||
() => this.check(),
|
||||
ConnectionKeepAliveHandler.pingTimeout
|
||||
)
|
||||
this.sendPingMessage()
|
||||
}
|
||||
|
||||
public stopTimer(): void {
|
||||
clearInterval(this.intervalId)
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a pong has been received since the last run. If not, the connection is probably dead and will be terminated.
|
||||
*/
|
||||
private check(): void {
|
||||
if (this.pongReceived) {
|
||||
this.pongReceived = false
|
||||
this.sendPingMessage()
|
||||
} else {
|
||||
this.messageTransporter.disconnect()
|
||||
console.error(
|
||||
`No pong received in the last ${ConnectionKeepAliveHandler.pingTimeout} seconds. Connection seems to be dead.`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private sendPingMessage(): void {
|
||||
const encoder = createEncoder()
|
||||
writeVarUint(encoder, MessageType.PING)
|
||||
this.messageTransporter.send(toUint8Array(encoder))
|
||||
}
|
||||
|
||||
private sendPongMessage(): void {
|
||||
const encoder = createEncoder()
|
||||
writeVarUint(encoder, MessageType.PONG)
|
||||
this.messageTransporter.send(toUint8Array(encoder))
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue