fix(core): update
This commit is contained in:
@ -2,4 +2,9 @@ export interface IRequestAuthPayload {
|
||||
serverShortId: string;
|
||||
}
|
||||
|
||||
export type TConnectionStatus = 'new' | 'connecting' | 'connected' | 'disconnecting' | 'disconnected';
|
||||
export type TConnectionStatus =
|
||||
| 'new'
|
||||
| 'connecting'
|
||||
| 'connected'
|
||||
| 'disconnecting'
|
||||
| 'disconnected';
|
||||
|
@ -2,7 +2,11 @@ import * as plugins from './smartsocket.plugins';
|
||||
|
||||
// classes
|
||||
import { SocketConnection } from './smartsocket.classes.socketconnection';
|
||||
import { ISocketFunctionCallDataRequest, SocketFunction, ISocketFunctionCallDataResponse } from './smartsocket.classes.socketfunction';
|
||||
import {
|
||||
ISocketFunctionCallDataRequest,
|
||||
SocketFunction,
|
||||
ISocketFunctionCallDataResponse,
|
||||
} from './smartsocket.classes.socketfunction';
|
||||
import { SocketRequest } from './smartsocket.classes.socketrequest';
|
||||
import { SocketRole } from './smartsocket.classes.socketrole';
|
||||
import { SocketServer } from './smartsocket.classes.socketserver';
|
||||
@ -44,7 +48,7 @@ export class Smartsocket {
|
||||
public async start() {
|
||||
this.io = plugins.socketIo(this.socketServer.getServerForSocketIo());
|
||||
await this.socketServer.start();
|
||||
this.io.on('connection', socketArg => {
|
||||
this.io.on('connection', (socketArg) => {
|
||||
this._handleSocketConnection(socketArg);
|
||||
});
|
||||
}
|
||||
@ -55,10 +59,7 @@ export class Smartsocket {
|
||||
public async stop() {
|
||||
await plugins.smartdelay.delayFor(1000);
|
||||
this.socketConnections.forEach((socketObjectArg: SocketConnection) => {
|
||||
logger.log(
|
||||
'info',
|
||||
`disconnect socket with >>alias ${socketObjectArg.alias}`
|
||||
);
|
||||
logger.log('info', `disconnect socket with >>alias ${socketObjectArg.alias}`);
|
||||
socketObjectArg.socket.disconnect();
|
||||
});
|
||||
this.socketConnections.wipe();
|
||||
@ -81,11 +82,11 @@ export class Smartsocket {
|
||||
const socketRequest = new SocketRequest<T>(this, {
|
||||
funcCallData: {
|
||||
funcDataArg: dataArg,
|
||||
funcName: functionNameArg
|
||||
funcName: functionNameArg,
|
||||
},
|
||||
originSocketConnection: targetSocketConnectionArg,
|
||||
shortId: plugins.smartunique.shortId(),
|
||||
side: 'requesting'
|
||||
side: 'requesting',
|
||||
});
|
||||
const response: ISocketFunctionCallDataResponse<T> = await socketRequest.dispatch();
|
||||
const result = response.funcDataArg;
|
||||
@ -116,7 +117,7 @@ export class Smartsocket {
|
||||
role: undefined,
|
||||
side: 'server',
|
||||
smartsocketHost: this,
|
||||
socket: socketArg
|
||||
socket: socketArg,
|
||||
});
|
||||
logger.log('info', 'Socket connected. Trying to authenticate...');
|
||||
this.socketConnections.add(socketConnection);
|
||||
|
@ -2,7 +2,10 @@ import * as plugins from './smartsocket.plugins';
|
||||
import * as interfaces from './interfaces';
|
||||
|
||||
import { SocketConnection } from './smartsocket.classes.socketconnection';
|
||||
import { ISocketFunctionCallDataRequest, SocketFunction } from './smartsocket.classes.socketfunction';
|
||||
import {
|
||||
ISocketFunctionCallDataRequest,
|
||||
SocketFunction,
|
||||
} from './smartsocket.classes.socketfunction';
|
||||
import { ISocketRequestDataObject, SocketRequest } from './smartsocket.classes.socketrequest';
|
||||
import { SocketRole } from './smartsocket.classes.socketrole';
|
||||
import { logger } from './smartsocket.logging';
|
||||
@ -47,7 +50,7 @@ export class SmartsocketClient {
|
||||
this.serverPort = optionsArg.port;
|
||||
this.socketRole = new SocketRole({
|
||||
name: optionsArg.role,
|
||||
passwordHash: optionsArg.password
|
||||
passwordHash: optionsArg.password,
|
||||
});
|
||||
this.autoReconnect = optionsArg.autoReconnect;
|
||||
}
|
||||
@ -73,7 +76,7 @@ export class SmartsocketClient {
|
||||
socket: plugins.socketIoClient(socketUrl, {
|
||||
multiplex: false,
|
||||
reconnectionAttempts: 5,
|
||||
})
|
||||
}),
|
||||
});
|
||||
|
||||
const timer = new plugins.smarttime.Timer(5000);
|
||||
@ -84,33 +87,35 @@ export class SmartsocketClient {
|
||||
});
|
||||
|
||||
// authentication flow
|
||||
this.socketConnection.socket.on('requestAuth', (requestAuthPayload: interfaces.IRequestAuthPayload) => {
|
||||
timer.reset();
|
||||
logger.log('info', 'server requested authentication');
|
||||
|
||||
// lets register the authenticated event
|
||||
this.socketConnection.socket.on('authenticated', () => {
|
||||
this.remoteShortId = requestAuthPayload.serverShortId;
|
||||
logger.log('info', 'client is authenticated');
|
||||
this.socketConnection.authenticated = true;
|
||||
this.socketConnection.listenToFunctionRequests();
|
||||
done.resolve();
|
||||
});
|
||||
this.socketConnection.socket.on(
|
||||
'requestAuth',
|
||||
(requestAuthPayload: interfaces.IRequestAuthPayload) => {
|
||||
timer.reset();
|
||||
logger.log('info', 'server requested authentication');
|
||||
|
||||
// lets register the forbidden event
|
||||
this.socketConnection.socket.on('forbidden', async () => {
|
||||
logger.log('warn', `disconnecting due to being forbidden to use the ressource`);
|
||||
await this.disconnect();
|
||||
});
|
||||
// lets register the authenticated event
|
||||
this.socketConnection.socket.on('authenticated', () => {
|
||||
this.remoteShortId = requestAuthPayload.serverShortId;
|
||||
logger.log('info', 'client is authenticated');
|
||||
this.socketConnection.authenticated = true;
|
||||
this.socketConnection.listenToFunctionRequests();
|
||||
done.resolve();
|
||||
});
|
||||
|
||||
// lets provide the actual auth data
|
||||
this.socketConnection.socket.emit('dataAuth', {
|
||||
role: this.socketRole.name,
|
||||
password: this.socketRole.passwordHash,
|
||||
alias: this.alias
|
||||
});
|
||||
// lets register the forbidden event
|
||||
this.socketConnection.socket.on('forbidden', async () => {
|
||||
logger.log('warn', `disconnecting due to being forbidden to use the ressource`);
|
||||
await this.disconnect();
|
||||
});
|
||||
|
||||
});
|
||||
// lets provide the actual auth data
|
||||
this.socketConnection.socket.emit('dataAuth', {
|
||||
role: this.socketRole.name,
|
||||
password: this.socketRole.passwordHash,
|
||||
alias: this.alias,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// handle connection
|
||||
this.socketConnection.socket.on('connect', async () => {
|
||||
@ -159,10 +164,13 @@ export class SmartsocketClient {
|
||||
|
||||
/**
|
||||
* dispatches a server call
|
||||
* @param functionNameArg
|
||||
* @param dataArg
|
||||
* @param functionNameArg
|
||||
* @param dataArg
|
||||
*/
|
||||
public async serverCall<T extends plugins.typedrequestInterfaces.ITypedRequest>(functionNameArg: T['method'], dataArg: T['request']): Promise<T['response']> {
|
||||
public async serverCall<T extends plugins.typedrequestInterfaces.ITypedRequest>(
|
||||
functionNameArg: T['method'],
|
||||
dataArg: T['request']
|
||||
): Promise<T['response']> {
|
||||
const done = plugins.smartpromise.defer();
|
||||
const socketRequest = new SocketRequest<T>(this, {
|
||||
side: 'requesting',
|
||||
@ -170,15 +178,15 @@ export class SmartsocketClient {
|
||||
shortId: plugins.smartunique.shortId(),
|
||||
funcCallData: {
|
||||
funcName: functionNameArg,
|
||||
funcDataArg: dataArg
|
||||
}
|
||||
funcDataArg: dataArg,
|
||||
},
|
||||
});
|
||||
const response = await socketRequest.dispatch();
|
||||
const result = response.funcDataArg;
|
||||
return result;
|
||||
}
|
||||
|
||||
private updateStatus (statusArg: interfaces.TConnectionStatus) {
|
||||
private updateStatus(statusArg: interfaces.TConnectionStatus) {
|
||||
if (this.eventStatus !== statusArg) {
|
||||
this.eventSubject.next(statusArg);
|
||||
}
|
||||
|
@ -90,10 +90,7 @@ export class SocketConnection {
|
||||
public authenticate() {
|
||||
const done = plugins.smartpromise.defer();
|
||||
this.socket.on('dataAuth', async (dataArg: ISocketConnectionAuthenticationObject) => {
|
||||
logger.log(
|
||||
'info',
|
||||
'received authentication data. now hashing and comparing...'
|
||||
);
|
||||
logger.log('info', 'received authentication data. now hashing and comparing...');
|
||||
this.socket.removeListener('dataAuth', () => {});
|
||||
if (SocketRole.checkPasswordForRole(dataArg, this.smartsocketRef)) {
|
||||
// TODO: authenticate password
|
||||
@ -101,10 +98,7 @@ export class SocketConnection {
|
||||
this.authenticated = true;
|
||||
this.role = SocketRole.getSocketRoleByName(this.smartsocketRef, dataArg.role);
|
||||
this.socket.emit('authenticated');
|
||||
logger.log(
|
||||
'ok',
|
||||
`socket with >>alias ${this.alias} >>role ${this.role} is authenticated!`
|
||||
);
|
||||
logger.log('ok', `socket with >>alias ${this.alias} >>role ${this.role} is authenticated!`);
|
||||
done.resolve(this);
|
||||
} else {
|
||||
this.authenticated = false;
|
||||
@ -113,7 +107,7 @@ export class SocketConnection {
|
||||
}
|
||||
});
|
||||
const requestAuthPayload: interfaces.IRequestAuthPayload = {
|
||||
serverShortId: this.smartsocketRef.shortId
|
||||
serverShortId: this.smartsocketRef.shortId,
|
||||
};
|
||||
this.socket.emit('requestAuth', requestAuthPayload);
|
||||
return done.promise;
|
||||
@ -131,7 +125,7 @@ export class SocketConnection {
|
||||
// check if requested function is available to the socket's scope
|
||||
logger.log('info', 'function request received');
|
||||
const referencedFunction: SocketFunction<any> = this.role.allowedFunctions.find(
|
||||
socketFunctionArg => {
|
||||
(socketFunctionArg) => {
|
||||
return socketFunctionArg.name === dataArg.funcCallData.funcName;
|
||||
}
|
||||
);
|
||||
@ -141,31 +135,22 @@ export class SocketConnection {
|
||||
side: 'responding',
|
||||
originSocketConnection: this,
|
||||
shortId: dataArg.shortId,
|
||||
funcCallData: dataArg.funcCallData
|
||||
funcCallData: dataArg.funcCallData,
|
||||
});
|
||||
localSocketRequest.createResponse(); // takes care of creating response and sending it back
|
||||
} else {
|
||||
logger.log(
|
||||
'warn',
|
||||
'function not existent or out of access scope'
|
||||
);
|
||||
logger.log('warn', 'function not existent or out of access scope');
|
||||
}
|
||||
});
|
||||
this.socket.on('functionResponse', (dataArg: ISocketRequestDataObject<any>) => {
|
||||
logger.log(
|
||||
'info',
|
||||
`received response for request with id ${dataArg.shortId}`
|
||||
);
|
||||
logger.log('info', `received response for request with id ${dataArg.shortId}`);
|
||||
const targetSocketRequest = SocketRequest.getSocketRequestById(
|
||||
this.smartsocketRef,
|
||||
dataArg.shortId
|
||||
);
|
||||
targetSocketRequest.handleResponse(dataArg);
|
||||
});
|
||||
logger.log(
|
||||
'info',
|
||||
`now listening to function requests for ${this.alias}`
|
||||
);
|
||||
logger.log('info', `now listening to function requests for ${this.alias}`);
|
||||
done.resolve(this);
|
||||
} else {
|
||||
const errMessage = 'socket needs to be authenticated first';
|
||||
@ -181,7 +166,7 @@ export class SocketConnection {
|
||||
this.updateStatus('disconnected');
|
||||
}
|
||||
|
||||
private updateStatus (statusArg: interfaces.TConnectionStatus) {
|
||||
private updateStatus(statusArg: interfaces.TConnectionStatus) {
|
||||
if (this.eventStatus !== statusArg) {
|
||||
this.eventSubject.next(statusArg);
|
||||
}
|
||||
|
@ -11,7 +11,9 @@ import { SmartsocketClient } from './smartsocket.classes.smartsocketclient';
|
||||
/**
|
||||
* interface of the contructor options of class SocketFunction
|
||||
*/
|
||||
export interface ISocketFunctionConstructorOptions<T extends plugins.typedrequestInterfaces.ITypedRequest> {
|
||||
export interface ISocketFunctionConstructorOptions<
|
||||
T extends plugins.typedrequestInterfaces.ITypedRequest
|
||||
> {
|
||||
funcName: T['method'];
|
||||
funcDef: TFuncDef<T>;
|
||||
allowedRoles: SocketRole[]; // all roles that are allowed to execute a SocketFunction
|
||||
@ -20,7 +22,9 @@ export interface ISocketFunctionConstructorOptions<T extends plugins.typedreques
|
||||
/**
|
||||
* interface of the Socket Function call, in other words the object that routes a call to a function
|
||||
*/
|
||||
export interface ISocketFunctionCallDataRequest<T extends plugins.typedrequestInterfaces.ITypedRequest> {
|
||||
export interface ISocketFunctionCallDataRequest<
|
||||
T extends plugins.typedrequestInterfaces.ITypedRequest
|
||||
> {
|
||||
funcName: T['method'];
|
||||
funcDataArg: T['request'];
|
||||
}
|
||||
@ -28,7 +32,9 @@ export interface ISocketFunctionCallDataRequest<T extends plugins.typedrequestIn
|
||||
/**
|
||||
* interface of the Socket Function call, in other words the object that routes a call to a function
|
||||
*/
|
||||
export interface ISocketFunctionCallDataResponse<T extends plugins.typedrequestInterfaces.ITypedRequest> {
|
||||
export interface ISocketFunctionCallDataResponse<
|
||||
T extends plugins.typedrequestInterfaces.ITypedRequest
|
||||
> {
|
||||
funcName: T['method'];
|
||||
funcDataArg: T['response'];
|
||||
}
|
||||
@ -36,7 +42,10 @@ export interface ISocketFunctionCallDataResponse<T extends plugins.typedrequestI
|
||||
/**
|
||||
* interface for function definition of SocketFunction
|
||||
*/
|
||||
export type TFuncDef<T extends plugins.typedrequestInterfaces.ITypedRequest> = (dataArg: T['request'], connectionArg: SocketConnection) => PromiseLike<T['response']>;
|
||||
export type TFuncDef<T extends plugins.typedrequestInterfaces.ITypedRequest> = (
|
||||
dataArg: T['request'],
|
||||
connectionArg: SocketConnection
|
||||
) => PromiseLike<T['response']>;
|
||||
|
||||
// export classes
|
||||
|
||||
@ -49,7 +58,7 @@ export class SocketFunction<T extends plugins.typedrequestInterfaces.ITypedReque
|
||||
smartsocketRefArg: Smartsocket | SmartsocketClient,
|
||||
functionNameArg: string
|
||||
): SocketFunction<Q> {
|
||||
return smartsocketRefArg.socketFunctions.find(socketFunctionArg => {
|
||||
return smartsocketRefArg.socketFunctions.find((socketFunctionArg) => {
|
||||
return socketFunctionArg.name === functionNameArg;
|
||||
});
|
||||
}
|
||||
@ -74,11 +83,14 @@ export class SocketFunction<T extends plugins.typedrequestInterfaces.ITypedReque
|
||||
/**
|
||||
* invokes the function of this SocketFunction
|
||||
*/
|
||||
public async invoke(dataArg: ISocketFunctionCallDataRequest<T>, socketConnectionArg: SocketConnection): Promise<ISocketFunctionCallDataResponse<T>> {
|
||||
public async invoke(
|
||||
dataArg: ISocketFunctionCallDataRequest<T>,
|
||||
socketConnectionArg: SocketConnection
|
||||
): Promise<ISocketFunctionCallDataResponse<T>> {
|
||||
if (dataArg.funcName === this.name) {
|
||||
const funcResponseData: ISocketFunctionCallDataResponse<T> = {
|
||||
funcName: this.name,
|
||||
funcDataArg: await this.funcDef(dataArg.funcDataArg, socketConnectionArg)
|
||||
funcDataArg: await this.funcDef(dataArg.funcDataArg, socketConnectionArg),
|
||||
};
|
||||
return funcResponseData;
|
||||
} else {
|
||||
|
@ -1,7 +1,11 @@
|
||||
import * as plugins from './smartsocket.plugins';
|
||||
|
||||
// import interfaces
|
||||
import { SocketFunction, ISocketFunctionCallDataRequest, ISocketFunctionCallDataResponse } from './smartsocket.classes.socketfunction';
|
||||
import {
|
||||
SocketFunction,
|
||||
ISocketFunctionCallDataRequest,
|
||||
ISocketFunctionCallDataResponse,
|
||||
} from './smartsocket.classes.socketfunction';
|
||||
|
||||
// import classes
|
||||
import { SocketConnection } from './smartsocket.classes.socketconnection';
|
||||
@ -16,7 +20,9 @@ export type TSocketRequestSide = 'requesting' | 'responding';
|
||||
/**
|
||||
* interface of constructor of class SocketRequest
|
||||
*/
|
||||
export interface ISocketRequestConstructorOptions<T extends plugins.typedrequestInterfaces.ITypedRequest> {
|
||||
export interface ISocketRequestConstructorOptions<
|
||||
T extends plugins.typedrequestInterfaces.ITypedRequest
|
||||
> {
|
||||
side: TSocketRequestSide;
|
||||
originSocketConnection: SocketConnection;
|
||||
shortId: string;
|
||||
@ -39,7 +45,7 @@ export class SocketRequest<T extends plugins.typedrequestInterfaces.ITypedReques
|
||||
smartsocketRef: Smartsocket | SmartsocketClient,
|
||||
shortIdArg: string
|
||||
): SocketRequest<any> {
|
||||
return smartsocketRef.socketRequests.find(socketRequestArg => {
|
||||
return smartsocketRef.socketRequests.find((socketRequestArg) => {
|
||||
return socketRequestArg.shortid === shortIdArg;
|
||||
});
|
||||
}
|
||||
@ -74,7 +80,7 @@ export class SocketRequest<T extends plugins.typedrequestInterfaces.ITypedReques
|
||||
public dispatch(): Promise<ISocketFunctionCallDataResponse<T>> {
|
||||
const requestData: ISocketRequestDataObject<T> = {
|
||||
funcCallData: this.funcCallData,
|
||||
shortId: this.shortid
|
||||
shortId: this.shortid,
|
||||
};
|
||||
this.originSocketConnection.socket.emit('function', requestData);
|
||||
return this.done.promise;
|
||||
@ -101,22 +107,21 @@ export class SocketRequest<T extends plugins.typedrequestInterfaces.ITypedReques
|
||||
);
|
||||
|
||||
if (!targetSocketFunction) {
|
||||
logger.log(
|
||||
'warn',
|
||||
`There is no SocketFunction defined for ${this.funcCallData.funcName}`
|
||||
);
|
||||
logger.log('warn', `There is no SocketFunction defined for ${this.funcCallData.funcName}`);
|
||||
logger.log('warn', `So now response is being sent.`);
|
||||
return;
|
||||
}
|
||||
logger.log('info', `invoking ${targetSocketFunction.name}`);
|
||||
targetSocketFunction.invoke(this.funcCallData, this.originSocketConnection).then(resultData => {
|
||||
logger.log('info', 'got resultData. Sending it to requesting party.');
|
||||
const responseData: ISocketRequestDataObject<T> = {
|
||||
funcCallData: resultData,
|
||||
shortId: this.shortid
|
||||
};
|
||||
this.originSocketConnection.socket.emit('functionResponse', responseData);
|
||||
this.smartsocketRef.socketRequests.remove(this);
|
||||
});
|
||||
targetSocketFunction
|
||||
.invoke(this.funcCallData, this.originSocketConnection)
|
||||
.then((resultData) => {
|
||||
logger.log('info', 'got resultData. Sending it to requesting party.');
|
||||
const responseData: ISocketRequestDataObject<T> = {
|
||||
funcCallData: resultData,
|
||||
shortId: this.shortid,
|
||||
};
|
||||
this.originSocketConnection.socket.emit('functionResponse', responseData);
|
||||
this.smartsocketRef.socketRequests.remove(this);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ export class SocketRole {
|
||||
referenceSmartsocket: Smartsocket | SmartsocketClient,
|
||||
socketRoleNameArg: string
|
||||
): SocketRole {
|
||||
return referenceSmartsocket.socketRoles.find(socketRoleArg => {
|
||||
return referenceSmartsocket.socketRoles.find((socketRoleArg) => {
|
||||
return socketRoleArg.name === socketRoleNameArg;
|
||||
});
|
||||
}
|
||||
|
@ -60,7 +60,10 @@ export class SocketServer {
|
||||
throw new Error('there should be a port specified for smartsocket');
|
||||
}
|
||||
this.httpServer.listen(this.smartsocket.options.port, () => {
|
||||
logger.log('success', `Server started in standalone mode on ${this.smartsocket.options.port}`);
|
||||
logger.log(
|
||||
'success',
|
||||
`Server started in standalone mode on ${this.smartsocket.options.port}`
|
||||
);
|
||||
done.resolve();
|
||||
});
|
||||
} else {
|
||||
|
@ -1,3 +1,3 @@
|
||||
import * as plugins from './smartsocket.plugins';
|
||||
|
||||
export const logger = new plugins.smartlog.ConsoleLog();
|
||||
export const logger = new plugins.smartlog.ConsoleLog();
|
||||
|
@ -1,7 +1,7 @@
|
||||
// apiglobal scope
|
||||
import * as typedrequestInterfaces from '@apiglobal/typedrequest-interfaces';
|
||||
|
||||
export {typedrequestInterfaces};
|
||||
export { typedrequestInterfaces };
|
||||
|
||||
// pushrocks scope
|
||||
import * as lik from '@pushrocks/lik';
|
||||
@ -14,7 +14,6 @@ import * as smarttime from '@pushrocks/smarttime';
|
||||
import * as smartunique from '@pushrocks/smartunique';
|
||||
import * as smartrx from '@pushrocks/smartrx';
|
||||
|
||||
|
||||
export {
|
||||
lik,
|
||||
smartlog,
|
||||
@ -24,14 +23,11 @@ export {
|
||||
smartpromise,
|
||||
smarttime,
|
||||
smartunique,
|
||||
smartrx
|
||||
smartrx,
|
||||
};
|
||||
|
||||
// third party scope
|
||||
import socketIo from 'socket.io';
|
||||
import socketIoClient from 'socket.io-client';
|
||||
|
||||
export {
|
||||
socketIo,
|
||||
socketIoClient
|
||||
};
|
||||
export { socketIo, socketIoClient };
|
||||
|
Reference in New Issue
Block a user