feat(realtime): add disconnect reason

The frontend now doesn't try to reconnect, when the disconnection happened because of a lack of permissions

Signed-off-by: Philip Molares <philip.molares@udo.edu>
This commit is contained in:
Philip Molares 2023-10-22 21:33:34 +02:00
parent f6cfe74d8c
commit 723f3f611c
11 changed files with 111 additions and 46 deletions

View file

@ -0,0 +1,9 @@
/*
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
export enum DisconnectReason {
USER_NOT_PERMITTED = 4000
}

View file

@ -9,3 +9,4 @@ export * from './message-transporter.js'
export * from './realtime-user.js'
export * from './transport-adapter.js'
export * from './mocked-backend-transport-adapter.js'
export * from './disconnect_reason.js'

View file

@ -1,17 +1,25 @@
/*
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { Message, MessagePayloads, MessageType } from './message.js'
import {
ConnectionStateEvent,
Message,
MessagePayloads,
MessageType
} from './message.js'
import { TransportAdapter } from './transport-adapter.js'
import { EventEmitter2, Listener } from 'eventemitter2'
import { DisconnectReason } from './disconnect_reason.js'
export type MessageEvents = MessageType | 'connected' | 'disconnected' | 'ready'
export type AllEvents = MessageType | ConnectionStateEvent
type MessageEventPayloadMap = {
[E in MessageEvents]: E extends keyof MessagePayloads
[E in AllEvents]: E extends keyof MessagePayloads
? (message: Message<E>) => void
: E extends ConnectionStateEvent.DISCONNECTED
? (reason?: DisconnectReason) => void
: () => void
}
@ -157,14 +165,14 @@ export class MessageTransporter extends EventEmitter2<MessageEventPayloadMap> {
}
}
private bindWebsocketEvents(websocket: TransportAdapter) {
this.destroyOnErrorEventHandler = websocket.bindOnErrorEvent(
private bindWebsocketEvents(transportAdapter: TransportAdapter) {
this.destroyOnErrorEventHandler = transportAdapter.bindOnErrorEvent(
this.onDisconnecting.bind(this)
)
this.destroyOnCloseEventHandler = websocket.bindOnCloseEvent(
this.destroyOnCloseEventHandler = transportAdapter.bindOnCloseEvent(
this.onDisconnecting.bind(this)
)
this.destroyOnMessageEventHandler = websocket.bindOnMessageEvent(
this.destroyOnMessageEventHandler = transportAdapter.bindOnMessageEvent(
this.receiveMessage.bind(this)
)
}
@ -172,10 +180,10 @@ export class MessageTransporter extends EventEmitter2<MessageEventPayloadMap> {
protected onConnected(): void {
this.destroyOnConnectedEventHandler?.()
this.destroyOnConnectedEventHandler = undefined
this.emit('connected')
this.emit(ConnectionStateEvent.CONNECTED)
}
protected onDisconnecting(): void {
protected onDisconnecting(reason?: DisconnectReason): void {
if (this.transportAdapter === undefined) {
return
}
@ -184,7 +192,7 @@ export class MessageTransporter extends EventEmitter2<MessageEventPayloadMap> {
this.thisSideReady = false
this.otherSideReady = false
this.transportAdapter = undefined
this.emit('disconnected')
this.emit(ConnectionStateEvent.DISCONNECTED, reason)
}
/**

View file

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
@ -22,6 +22,12 @@ export enum MessageType {
READY_ANSWER = 'READY_ANSWER'
}
export enum ConnectionStateEvent {
READY = 'ready',
CONNECTED = 'connected',
DISCONNECTED = 'disconnected'
}
export interface MessagePayloads {
[MessageType.NOTE_CONTENT_STATE_REQUEST]: number[]
[MessageType.NOTE_CONTENT_UPDATE]: number[]

View file

@ -5,6 +5,7 @@
*/
import { ConnectionState } from './message-transporter.js'
import { Message, MessageType } from './message.js'
import { DisconnectReason } from './disconnect_reason.js'
/**
* Defines methods that must be implemented to send and receive messages using an {@link AdapterMessageTransporter}.
@ -18,7 +19,7 @@ export interface TransportAdapter {
bindOnErrorEvent(handler: () => void): () => void
bindOnCloseEvent(handler: () => void): () => void
bindOnCloseEvent(handler: (reason?: DisconnectReason) => void): () => void
disconnect(): void