nitro/libs/renderer/src/nitro/communication/NitroCommunicationDemo.ts

178 lines
5.6 KiB
TypeScript

import {IConnection, INitroCommunicationDemo, INitroCommunicationManager, NitroConfiguration, NitroLogger} from "../../api";
import {NitroManager} from "../../core";
import {NitroCommunicationDemoEvent, SocketConnectionEvent} from "../../events";
import {GetTickerTime} from "../../pixi-proxy";
import {Nitro} from "../Nitro";
import {
AuthenticatedEvent,
ClientHelloMessageComposer,
ClientPingEvent,
InfoRetrieveMessageComposer,
PongMessageComposer,
SSOTicketMessageComposer,
} from "./messages";
export class NitroCommunicationDemo extends NitroManager implements INitroCommunicationDemo {
private _communication: INitroCommunicationManager;
private _handShaking: boolean;
private _didConnect: boolean;
private _pongInterval: any;
constructor(communication: INitroCommunicationManager) {
super();
this._communication = communication;
this._handShaking = false;
this._didConnect = false;
this._pongInterval = null;
this.onConnectionOpenedEvent = this.onConnectionOpenedEvent.bind(this);
this.onConnectionClosedEvent = this.onConnectionClosedEvent.bind(this);
this.onConnectionErrorEvent = this.onConnectionErrorEvent.bind(this);
this.sendPong = this.sendPong.bind(this);
}
protected override onInit(): void {
const connection = this._communication.connection;
if (connection) {
connection.addEventListener(SocketConnectionEvent.CONNECTION_OPENED, this.onConnectionOpenedEvent);
connection.addEventListener(SocketConnectionEvent.CONNECTION_CLOSED, this.onConnectionClosedEvent);
connection.addEventListener(SocketConnectionEvent.CONNECTION_ERROR, this.onConnectionErrorEvent);
}
this._communication.registerMessageEvent(new ClientPingEvent(this.onClientPingEvent.bind(this)));
this._communication.registerMessageEvent(new AuthenticatedEvent(this.onAuthenticatedEvent.bind(this)));
}
protected override onDispose(): void {
const connection = this._communication.connection;
if (connection) {
connection.removeEventListener(SocketConnectionEvent.CONNECTION_OPENED, this.onConnectionOpenedEvent);
connection.removeEventListener(SocketConnectionEvent.CONNECTION_CLOSED, this.onConnectionClosedEvent);
connection.removeEventListener(SocketConnectionEvent.CONNECTION_ERROR, this.onConnectionErrorEvent);
}
this._handShaking = false;
this.stopPonging();
super.onDispose();
}
private onConnectionOpenedEvent(event: Event): void {
const connection = this._communication.connection;
if (!connection) return;
this._didConnect = true;
this.dispatchCommunicationDemoEvent(NitroCommunicationDemoEvent.CONNECTION_ESTABLISHED, connection);
if (NitroConfiguration.getValue<boolean>("system.pong.manually", false)) this.startPonging();
this.startHandshake(connection);
connection.send(new ClientHelloMessageComposer(null, null, null, null));
this.tryAuthentication(connection);
}
private onConnectionClosedEvent(event: CloseEvent): void {
const connection = this._communication.connection;
if (!connection) return;
this.stopPonging();
if (this._didConnect) this.dispatchCommunicationDemoEvent(NitroCommunicationDemoEvent.CONNECTION_CLOSED, connection);
}
private onConnectionErrorEvent(event: CloseEvent): void {
const connection = this._communication.connection;
if (!connection) return;
this.stopPonging();
this.dispatchCommunicationDemoEvent(NitroCommunicationDemoEvent.CONNECTION_ERROR, connection);
}
private tryAuthentication(connection: IConnection): void {
if (!connection || !this.getSSO()) {
if (!this.getSSO()) {
NitroLogger.error("Login without an SSO ticket is not supported");
}
this.dispatchCommunicationDemoEvent(NitroCommunicationDemoEvent.CONNECTION_HANDSHAKE_FAILED, connection);
return;
}
connection.send(new SSOTicketMessageComposer(this.getSSO(), GetTickerTime()));
}
private onClientPingEvent(event: ClientPingEvent): void {
if (!event || !event.connection) return;
this.sendPong(event.connection);
}
private onAuthenticatedEvent(event: AuthenticatedEvent): void {
if (!event || !event.connection) return;
this.completeHandshake(event.connection);
this.dispatchCommunicationDemoEvent(NitroCommunicationDemoEvent.CONNECTION_AUTHENTICATED, event.connection);
event.connection.send(new InfoRetrieveMessageComposer());
}
private startHandshake(connection: IConnection): void {
this.dispatchCommunicationDemoEvent(NitroCommunicationDemoEvent.CONNECTION_HANDSHAKING, connection);
this._handShaking = true;
}
private completeHandshake(connection: IConnection): void {
this.dispatchCommunicationDemoEvent(NitroCommunicationDemoEvent.CONNECTION_HANDSHAKED, connection);
this._handShaking = false;
}
private startPonging(): void {
this.stopPonging();
this._pongInterval = setInterval(this.sendPong, NitroConfiguration.getValue<number>("system.pong.interval.ms", 20000));
}
private stopPonging(): void {
if (!this._pongInterval) return;
clearInterval(this._pongInterval);
this._pongInterval = null;
}
private sendPong(connection: IConnection = null): void {
connection = connection || this._communication.connection || null;
if (!connection) return;
connection.send(new PongMessageComposer());
}
private dispatchCommunicationDemoEvent(type: string, connection: IConnection): void {
Nitro.instance.events.dispatchEvent(new NitroCommunicationDemoEvent(type, connection));
}
private getSSO(): string {
return NitroConfiguration.getValue("sso.ticket", null);
}
}