adapting bridge

This commit is contained in:
Martin Karkowski 2021-03-22 19:02:24 +01:00
parent 768d21f63c
commit 3742062684
2 changed files with 114 additions and 8 deletions

View File

@ -64,7 +64,7 @@ export class IoSocketClient extends Bridge implements ICommunicationInterface {
? new EventLayer(socket as any, this._logger)
: new MirrorLayer(socket as any, this._logger);
// 3. Add the Layer
this.addLayer(layer);
this.addLayer(layer, true, true);
socket.on("connect", (...args) => {
// Assign new ID.

View File

@ -10,12 +10,14 @@ import { EventEmitter } from "events";
import * as Logger from "js-logger";
import { ILogger } from "js-logger";
import { generateId } from "../helpers/idMethods";
import { copy } from "../helpers/objectMethods";
import { getNopeLogger } from "../logger/getLogger";
import { LoggerLevel } from "../logger/nopeLogger";
import { NopeObservable } from "../observables/nopeObservable";
import {
ICommunicationBridge,
ICommunicationInterface
ICommunicationInterface,
IEmitter
} from "../types/nope/nopeCommunication.interface";
import { INopeObservable } from "../types/nope/nopeObservable.interface";
@ -83,6 +85,30 @@ const METHOD_TO_EVENT: { [P in keyof ICommunicationInterface]: string } = {
emitRpcResponse: ""
};
const MIRROR_METHOD_MAPPING = copy(METHOD_TO_EVENT);
MIRROR_METHOD_MAPPING.onEvent = "event";
MIRROR_METHOD_MAPPING.emitEvent = "event";
MIRROR_METHOD_MAPPING.onRpcRequest = "rpcRequest";
MIRROR_METHOD_MAPPING.emitRpcRequest = "rpcRequest";
MIRROR_METHOD_MAPPING.onRpcRequest = "rpcResponse";
MIRROR_METHOD_MAPPING.emitRpcRequest = "rpcResponse";
const MIRROR_EVENT_TO_EMIT: {
[index: string]: keyof ICommunicationInterface;
} = {};
// Define all Events, that must be considered in a mirror.
const MIRROR_EVENTS = new Set(
Object.getOwnPropertyNames(MIRROR_METHOD_MAPPING).map((method) => {
if (method.startsWith("emit")) {
MIRROR_EVENT_TO_EMIT[
MIRROR_METHOD_MAPPING[method]
] = method as keyof ICommunicationInterface;
}
return MIRROR_METHOD_MAPPING[method];
})
);
const OFF_METHODS: Array<keyof ICommunicationInterface> = [
"offEvent",
"offRpcRequest",
@ -131,6 +157,8 @@ export class Bridge implements ICommunicationBridge {
}
>;
protected _mirrors: Set<IEmitter>;
protected _callbacks: Map<
string, // Method
Array<(...args) => any>
@ -158,6 +186,7 @@ export class Bridge implements ICommunicationBridge {
this._callbacks = new Map();
this._specificCallbacks = [];
this._layers = new Map();
this._mirrors = new Set();
this._logger = getNopeLogger(loggerName, level);
this.id = id;
@ -183,12 +212,12 @@ export class Bridge implements ICommunicationBridge {
}
for (const method of EMITTING_METHODS) {
this[method] = async (data) => {
_this._emit(method, data);
_this._emit(method, null, data);
};
}
for (const method of EMITTING_SPECIFIC_METHODS) {
this[method] = (event: string, data) => {
_this._emitSpecific(method, event, data);
this[method] = async (event: string, data) => {
_this._emitSpecific(method, null, event, data);
};
}
@ -224,7 +253,7 @@ export class Bridge implements ICommunicationBridge {
// Iterate over the layers and forward the Data to the other Layers
for (const data of this._layers.values()) {
if (data.layer !== layerToExclude) {
data.layer[method as any](...args).catch((error) => {
data.layer[MAPPING_METHODS[method] as any](...args).catch((error) => {
this._logger.error("failed forwarding", method, ...args);
this._logger.error(error);
});
@ -333,6 +362,7 @@ export class Bridge implements ICommunicationBridge {
this._internalEmitter.setMaxListeners(
this._internalEmitter.getMaxListeners() + 1
);
if (this._logger.enabledFor(Logger.DEBUG) && event !== "StatusUpdate") {
this._logger.debug("subscribe ", method, "specifically on", eventToUse);
@ -379,6 +409,7 @@ export class Bridge implements ICommunicationBridge {
protected _emit(
method: keyof ICommunicationInterface,
toExclude: ICommunicationInterface | IEmitter = null,
dataToSend: any
): void {
const event = METHOD_TO_EVENT[method];
@ -395,17 +426,25 @@ export class Bridge implements ICommunicationBridge {
// Iterate over the Layers.
for (const data of this._layers.values()) {
// If the Layer has been conneced
if (data.layer.connected.getContent()) {
if (data.layer !== toExclude && data.layer.connected.getContent()) {
// Only Publish the Data, on which we are forwarding
data.layer[method as any](dataToSend).catch((error) => {
_this._logger.error("failed executing", method);
_this._logger.error(error);
});
}
}
for (const mirror of this._mirrors) {
if (mirror != toExclude) {
mirror.emit(MIRROR_METHOD_MAPPING[method], dataToSend);
}
}
}
protected _emitSpecific(
method: keyof ICommunicationInterface,
toExclude: ICommunicationInterface | IEmitter = null,
event: string,
dataToSend: any
): void {
@ -425,13 +464,22 @@ export class Bridge implements ICommunicationBridge {
// Iterate over the Layers.
for (const data of this._layers.values()) {
// If the Layer has been conneced
if (data.layer.connected.getContent()) {
if (data.layer !== toExclude && data.layer.connected.getContent()) {
data.layer[method as any](event, dataToSend).catch((error) => {
_this._logger.error("failed executing", method);
_this._logger.error(error);
});
}
}
for (const mirror of this._mirrors) {
if (mirror != toExclude) {
mirror.emit(MIRROR_METHOD_MAPPING[method], {
name: event,
data: dataToSend
});
}
}
}
public async addLayer(
@ -477,4 +525,62 @@ export class Bridge implements ICommunicationBridge {
this._layers.delete(layer.id);
}
}
/**
* Adds a Mirror to the System.
*
* @param {IEmitter} mirror
* @return {*} {Promise<void>}
* @memberof Bridge
*/
public addMirror(mirror: IEmitter, addSubscriptions = true): void {
if (!this._mirrors.has(mirror)) {
this._mirrors.add(mirror);
if (addSubscriptions) {
const _this = this;
for (const eventName of MIRROR_EVENTS) {
if (!ON_SPECIFIC_METHODS.includes(eventName)) {
mirror.on(eventName, (data) => {
if (
_this._logger.enabledFor(Logger.DEBUG) &&
eventName !== "StatusUpdate"
) {
_this._logger.debug("received data from mirror on", eventName);
}
_this._emit(MIRROR_EVENT_TO_EMIT[eventName], mirror, data);
});
} else {
mirror.on(eventName, (data) => {
// If logging is enabled => Forward this information
if (
_this._logger.enabledFor(Logger.DEBUG) &&
eventName !== "StatusUpdate"
) {
_this._logger.debug(
"received data from mirror on",
eventName,
data.name
);
}
// Now emit the data on the channel
_this._emitSpecific(
MIRROR_EVENT_TO_EMIT[eventName],
mirror,
data.name,
data.data
);
});
}
}
}
}
}
public removeMirror(mirror: IEmitter): boolean {
return this._mirrors.delete(mirror);
}
}