update to latest standards

This commit is contained in:
2017-07-07 22:02:19 +02:00
parent f34358db81
commit 02065e36a6
31 changed files with 1613 additions and 810 deletions

View File

@ -1,12 +1,12 @@
import * as plugins from "./smartsocket.plugins";
import * as plugins from './smartsocket.plugins'
// export main classes
export * from "./smartsocket.classes.smartsocket";
export * from "./smartsocket.classes.smartsocketclient";
export * from './smartsocket.classes.smartsocket'
export * from './smartsocket.classes.smartsocketclient'
// export further classes and objects
export * from "./smartsocket.classes.socketfunction";
export * from "./smartsocket.classes.socketrole";
export * from "./smartsocket.classes.socketconnection";
export * from './smartsocket.classes.socketfunction'
export * from './smartsocket.classes.socketrole'
export * from './smartsocket.classes.socketconnection'
// need something more exposed? Create an issue on GitLab!

View File

@ -1,98 +1,98 @@
import * as plugins from "./smartsocket.plugins";
import * as helpers from "./smartsocket.helpers";
import * as plugins from './smartsocket.plugins'
import * as helpers from './smartsocket.helpers'
// classes
import { Objectmap } from "lik";
import { SocketFunction,ISocketFunctionCall} from "./smartsocket.classes.socketfunction";
import { SocketConnection } from "./smartsocket.classes.socketconnection";
import { SocketRequest } from "./smartsocket.classes.socketrequest";
import { SocketRole } from "./smartsocket.classes.socketrole";
import { Objectmap } from 'lik'
import { SocketFunction, ISocketFunctionCall } from './smartsocket.classes.socketfunction'
import { SocketConnection } from './smartsocket.classes.socketconnection'
import { SocketRequest } from './smartsocket.classes.socketrequest'
import { SocketRole } from './smartsocket.classes.socketrole'
export interface ISmartsocketConstructorOptions {
port: number;
};
port: number
}
export class Smartsocket {
options: ISmartsocketConstructorOptions
io: SocketIO.Server;
openSockets = new Objectmap<SocketConnection>();
socketRoles = new Objectmap<SocketRole>();
constructor(optionsArg: ISmartsocketConstructorOptions) {
this.options = optionsArg;
};
options: ISmartsocketConstructorOptions
io: SocketIO.Server
openSockets = new Objectmap<SocketConnection>()
socketRoles = new Objectmap<SocketRole>()
constructor (optionsArg: ISmartsocketConstructorOptions) {
this.options = optionsArg
}
/**
* the standard handler for new socket connections
*/
private _handleSocketConnection(socketArg) {
let socketConnection: SocketConnection = new SocketConnection({
alias:undefined,
authenticated:false,
role:undefined,
side:"server",
smartsocketHost: this,
socket:socketArg
});
plugins.beautylog.log("Socket connected. Trying to authenticate...")
this.openSockets.add(socketConnection);
socketConnection.authenticate()
.then(() => {
return socketConnection.listenToFunctionRequests();
})
.catch((err) => {
console.log(err);
});
};
/**
* starts listening to incling sockets:
*/
startServer = () => {
this.io = plugins.socketIo(this.options.port)
this.io.on('connection', (socketArg) => {
this._handleSocketConnection(socketArg)
})
}
closeServer = () => {
this.openSockets.forEach((socketObjectArg: SocketConnection) => {
plugins.beautylog.log(`disconnect socket with >>alias ${socketObjectArg.alias}`)
socketObjectArg.socket.disconnect()
})
this.openSockets.wipe()
this.io.close()
}
/**
* starts listening to incling sockets:
*/
startServer = () => {
this.io = plugins.socketIo(this.options.port);
this.io.on("connection", (socketArg) => {
this._handleSocketConnection(socketArg);
});
// communication
/**
* allows call to specific client.
*/
clientCall (functionNameArg: string, dataArg: any, targetSocketConnectionArg: SocketConnection) {
let done = plugins.smartq.defer()
let socketRequest = new SocketRequest({
side: 'requesting',
originSocketConnection: targetSocketConnectionArg,
shortId: plugins.shortid.generate(),
funcCallData: {
funcName: functionNameArg,
funcDataArg: dataArg
}
})
socketRequest.dispatch()
.then((dataArg: ISocketFunctionCall) => {
done.resolve(dataArg.funcDataArg)
})
return done.promise
}
/**
* adds socketRoles
*/
addSocketRoles (socketRolesArray: SocketRole[]): void {
for (let socketRole of socketRolesArray) {
this.socketRoles.add(socketRole)
}
closeServer = () => {
this.openSockets.forEach((socketObjectArg: SocketConnection) => {
plugins.beautylog.log(`disconnect socket with >>alias ${socketObjectArg.alias}`);
socketObjectArg.socket.disconnect();
});
this.openSockets.wipe();
this.io.close();
};
return
}
// communication
/**
* the standard handler for new socket connections
*/
private _handleSocketConnection (socketArg) {
let socketConnection: SocketConnection = new SocketConnection({
alias: undefined,
authenticated: false,
role: undefined,
side: 'server',
smartsocketHost: this,
socket: socketArg
})
plugins.beautylog.log('Socket connected. Trying to authenticate...')
this.openSockets.add(socketConnection)
socketConnection.authenticate()
.then(() => {
return socketConnection.listenToFunctionRequests()
})
.catch((err) => {
console.log(err)
})
}
/**
* allows call to specific client.
*/
clientCall(functionNameArg:string,dataArg:any,targetSocketConnectionArg:SocketConnection){
let done = plugins.q.defer();
let socketRequest = new SocketRequest({
side:"requesting",
originSocketConnection:targetSocketConnectionArg,
shortId:plugins.shortid.generate(),
funcCallData:{
funcName: functionNameArg,
funcDataArg:dataArg
}
});
socketRequest.dispatch()
.then((dataArg:ISocketFunctionCall) => {
done.resolve(dataArg.funcDataArg);
});
return done.promise;
};
/**
* adds socketRoles
*/
addSocketRoles(socketRolesArray:SocketRole[]):void{
for(let socketRole of socketRolesArray){
this.socketRoles.add(socketRole);
};
return;
};
}
}

View File

@ -1,95 +1,95 @@
import * as plugins from "./smartsocket.plugins"
import * as plugins from './smartsocket.plugins'
// import interfaces
import { ISocketFunctionCall } from "./smartsocket.classes.socketfunction";
import { ISocketRequestDataObject } from "./smartsocket.classes.socketrequest"
import { ISocketFunctionCall } from './smartsocket.classes.socketfunction'
import { ISocketRequestDataObject } from './smartsocket.classes.socketrequest'
// import classes
import { SocketConnection } from "./smartsocket.classes.socketconnection";
import { SocketFunction } from "./smartsocket.classes.socketfunction";
import { SocketRequest } from "./smartsocket.classes.socketrequest";
import { SocketConnection } from './smartsocket.classes.socketconnection'
import { SocketFunction } from './smartsocket.classes.socketfunction'
import { SocketRequest } from './smartsocket.classes.socketrequest'
/**
* interface for class SmartsocketClient
*/
export interface ISmartsocketClientOptions {
port: number;
url: string;
alias:string; // an alias makes it easier to identify this client in a multo client environment
role:string;
password: string; // by setting a password access to functions can be limited
port: number
url: string
alias: string // an alias makes it easier to identify this client in a multo client environment
role: string
password: string // by setting a password access to functions can be limited
}
export class SmartsocketClient {
alias:string;
role:string;
socketConnection:SocketConnection;
serverUrl:string;
serverPort:number;
serverPassword:string;
constructor(optionsArg:ISmartsocketClientOptions){
this.alias = optionsArg.alias;
this.role = optionsArg.role;
this.serverUrl = optionsArg.url
this.serverPort = optionsArg.port;
this.serverPassword = optionsArg.password
};
alias: string
role: string
socketConnection: SocketConnection
serverUrl: string
serverPort: number
serverPassword: string
constructor(optionsArg: ISmartsocketClientOptions) {
this.alias = optionsArg.alias
this.role = optionsArg.role
this.serverUrl = optionsArg.url
this.serverPort = optionsArg.port
this.serverPassword = optionsArg.password
}
/**
* connect the client to the server
*/
connect(){
let done = plugins.q.defer();
plugins.beautylog.log("trying to connect...");
let socketUrl = `${this.serverUrl}:${this.serverPort}`;
this.socketConnection = new SocketConnection({
alias:this.alias,
authenticated:false,
role:undefined,
side:"client",
smartsocketHost: null,
socket: plugins.socketIoClient(socketUrl,{multiplex:false})
});
this.socketConnection.socket.on("requestAuth", () => {
console.log("server requested authentication");
this.socketConnection.socket.emit("dataAuth", {
role: this.role,
password: this.serverPassword,
alias: this.alias
});
this.socketConnection.socket.on("authenticated",() => {
console.log("client is authenticated");
this.socketConnection.authenticated = true;
this.socketConnection.listenToFunctionRequests();
done.resolve();
});
});
return done.promise;
};
disconnect(){
let done = plugins.q.defer();
this.socketConnection.socket.disconnect();
this.socketConnection = undefined;
plugins.beautylog.ok("disconnected!");
done.resolve();
return done.promise;
}
serverCall(functionNameArg:string,dataArg:any){
let done = plugins.q.defer();
let socketRequest = new SocketRequest({
side:"requesting",
originSocketConnection:this.socketConnection,
shortId:plugins.shortid.generate(),
funcCallData:{
funcName: functionNameArg,
funcDataArg:dataArg
}
});
socketRequest.dispatch()
.then((dataArg:ISocketFunctionCall) => {
done.resolve(dataArg.funcDataArg);
});
return done.promise;
};
}
/**
* connect the client to the server
*/
connect () {
let done = plugins.smartq.defer()
plugins.beautylog.log('trying to connect...')
let socketUrl = `${this.serverUrl}:${this.serverPort}`
this.socketConnection = new SocketConnection({
alias: this.alias,
authenticated: false,
role: undefined,
side: 'client',
smartsocketHost: null,
socket: plugins.socketIoClient(socketUrl, { multiplex: false })
})
this.socketConnection.socket.on('requestAuth', () => {
console.log('server requested authentication')
this.socketConnection.socket.emit('dataAuth', {
role: this.role,
password: this.serverPassword,
alias: this.alias
})
this.socketConnection.socket.on('authenticated', () => {
console.log('client is authenticated')
this.socketConnection.authenticated = true
this.socketConnection.listenToFunctionRequests()
done.resolve()
})
})
return done.promise
}
disconnect () {
let done = plugins.smartq.defer()
this.socketConnection.socket.disconnect()
this.socketConnection = undefined
plugins.beautylog.ok('disconnected!')
done.resolve()
return done.promise
}
serverCall (functionNameArg: string, dataArg: any) {
let done = plugins.smartq.defer()
let socketRequest = new SocketRequest({
side: 'requesting',
originSocketConnection: this.socketConnection,
shortId: plugins.shortid.generate(),
funcCallData: {
funcName: functionNameArg,
funcDataArg: dataArg
}
})
socketRequest.dispatch()
.then((dataArg: ISocketFunctionCall) => {
done.resolve(dataArg.funcDataArg)
})
return done.promise
}
}

View File

@ -1,140 +1,140 @@
import * as plugins from "./smartsocket.plugins";
import * as helpers from "./smartsocket.helpers";
import * as plugins from './smartsocket.plugins'
import * as helpers from './smartsocket.helpers'
import {Objectmap} from "lik";
import { Objectmap } from 'lik'
// import classes
import { Smartsocket } from "./smartsocket.classes.smartsocket"
import { SocketFunction } from "./smartsocket.classes.socketfunction";
import { SocketRequest, ISocketRequestDataObject, allSocketRequests } from "./smartsocket.classes.socketrequest";
import { SocketRole } from "./smartsocket.classes.socketrole";
import { Smartsocket } from './smartsocket.classes.smartsocket'
import { SocketFunction } from './smartsocket.classes.socketfunction'
import { SocketRequest, ISocketRequestDataObject, allSocketRequests } from './smartsocket.classes.socketrequest'
import { SocketRole } from './smartsocket.classes.socketrole'
// export interfaces
/**
* defines is a SocketConnection is server or client side. Important for mesh setups.
*/
export type TSocketConnectionSide = "server" | "client";
export type TSocketConnectionSide = 'server' | 'client'
/**
* interface for constructor of class SocketConnection
*/
export interface ISocketConnectionConstructorOptions {
alias: string;
authenticated: boolean;
role: SocketRole;
side: TSocketConnectionSide;
smartsocketHost: Smartsocket;
socket: SocketIO.Socket | SocketIOClient.Socket;
};
alias: string
authenticated: boolean
role: SocketRole
side: TSocketConnectionSide
smartsocketHost: Smartsocket
socket: SocketIO.Socket | SocketIOClient.Socket
}
/**
* interface for authentication data
*/
export interface ISocketConnectionAuthenticationObject {
role: "coreflowContainer",
password: "somePassword",
alias: "coreflow1"
};
role: 'coreflowContainer',
password: 'somePassword',
alias: 'coreflow1'
}
// export classes
export let allSocketConnections = new Objectmap<SocketConnection>();
export let allSocketConnections = new Objectmap<SocketConnection>()
/**
* class SocketConnection represents a websocket connection
*/
export class SocketConnection {
alias: string;
side:TSocketConnectionSide;
authenticated: boolean = false;
role: SocketRole;
smartsocketHost:Smartsocket;
socket: SocketIO.Socket | SocketIOClient.Socket;
constructor(optionsArg: ISocketConnectionConstructorOptions) {
this.alias = optionsArg.alias;
this.authenticated = optionsArg.authenticated;
this.role = optionsArg.role;
this.side = optionsArg.side;
this.smartsocketHost = optionsArg.smartsocketHost;
this.socket = optionsArg.socket;
// standard behaviour that is always true
allSocketConnections.add(this);
this.socket.on("disconnect", () => {
plugins.beautylog.info(`SocketConnection with >alias ${this.alias} on >side ${this.side} disconnected`);
allSocketConnections.remove(this);
});
};
alias: string
side: TSocketConnectionSide
authenticated: boolean = false
role: SocketRole
smartsocketHost: Smartsocket
socket: any //: SocketIO.Socket | SocketIOClient.Socket
constructor (optionsArg: ISocketConnectionConstructorOptions) {
this.alias = optionsArg.alias
this.authenticated = optionsArg.authenticated
this.role = optionsArg.role
this.side = optionsArg.side
this.smartsocketHost = optionsArg.smartsocketHost
this.socket = optionsArg.socket
// authenticating --------------------------
// standard behaviour that is always true
allSocketConnections.add(this)
this.socket.on('disconnect', () => {
plugins.beautylog.info(`SocketConnection with >alias ${this.alias} on >side ${this.side} disconnected`)
allSocketConnections.remove(this)
})
}
/**
* authenticate the socket
*/
authenticate() {
let done = plugins.q.defer();
this.socket.on("dataAuth", (dataArg:ISocketConnectionAuthenticationObject) => {
plugins.beautylog.log("received authentication data. now hashing and comparing...");
this.socket.removeListener("dataAuth", () => { });
if (helpers.checkPasswordForRole(dataArg,this.smartsocketHost)) { // TODO: authenticate password
this.alias = dataArg.alias
this.authenticated = true;
this.role = helpers.getSocketRoleByName(dataArg.role,this.smartsocketHost);
this.socket.emit("authenticated");
plugins.beautylog.ok(`socket with >>alias ${this.alias} >>role ${this.role} is authenticated!`);
done.resolve(this);
} else {
this.authenticated = false;
this.socket.disconnect();
done.reject("not authenticated");
};
});
this.socket.emit("requestAuth");
return done.promise;
};
// authenticating --------------------------
// listening -------------------------------
/**
* authenticate the socket
*/
authenticate () {
let done = plugins.smartq.defer()
this.socket.on('dataAuth', (dataArg: ISocketConnectionAuthenticationObject) => {
plugins.beautylog.log('received authentication data. now hashing and comparing...')
this.socket.removeListener('dataAuth', () => { })
if (helpers.checkPasswordForRole(dataArg, this.smartsocketHost)) { // TODO: authenticate password
this.alias = dataArg.alias
this.authenticated = true
this.role = helpers.getSocketRoleByName(dataArg.role, this.smartsocketHost)
this.socket.emit('authenticated')
plugins.beautylog.ok(`socket with >>alias ${this.alias} >>role ${this.role} is authenticated!`)
done.resolve(this)
} else {
this.authenticated = false
this.socket.disconnect()
done.reject('not authenticated')
}
})
this.socket.emit('requestAuth')
return done.promise
}
/**
* listen to function requests
*/
listenToFunctionRequests(){
let done = plugins.q.defer();
if(this.authenticated){
this.socket.on("function", (dataArg:ISocketRequestDataObject) => {
// check if requested function is available to the socket's scope
plugins.beautylog.log("function request received");
let referencedFunction:SocketFunction = this.role.allowedFunctions.find((socketFunctionArg) => {
return socketFunctionArg.name === dataArg.funcCallData.funcName;
});
if(referencedFunction !== undefined){
plugins.beautylog.ok!("function in access scope");
let localSocketRequest = new SocketRequest({
side:"responding",
originSocketConnection:this,
shortId:dataArg.shortId,
funcCallData:dataArg.funcCallData
});
localSocketRequest.createResponse(); // takes care of creating response and sending it back
} else {
plugins.beautylog.warn("function not existent or out of access scope");
};
});
this.socket.on("functionResponse", (dataArg:ISocketRequestDataObject) => {
plugins.beautylog.info(`received response for request with id ${dataArg.shortId}`);
let targetSocketRequest = helpers.getSocketRequestById(dataArg.shortId);
targetSocketRequest.handleResponse(dataArg);
});
plugins.beautylog.log(`now listening to function requests for ${this.alias}`);
done.resolve(this);
// listening -------------------------------
/**
* listen to function requests
*/
listenToFunctionRequests () {
let done = plugins.smartq.defer()
if (this.authenticated) {
this.socket.on('function', (dataArg: ISocketRequestDataObject) => {
// check if requested function is available to the socket's scope
plugins.beautylog.log('function request received')
let referencedFunction: SocketFunction = this.role.allowedFunctions.find((socketFunctionArg) => {
return socketFunctionArg.name === dataArg.funcCallData.funcName
})
if (referencedFunction !== undefined) {
plugins.beautylog.ok!('function in access scope')
let localSocketRequest = new SocketRequest({
side: 'responding',
originSocketConnection: this,
shortId: dataArg.shortId,
funcCallData: dataArg.funcCallData
})
localSocketRequest.createResponse() // takes care of creating response and sending it back
} else {
let errMessage: "socket needs to be authenticated first";
plugins.beautylog.error(errMessage);
done.reject(errMessage);
};
return done.promise;
};
plugins.beautylog.warn('function not existent or out of access scope')
}
})
this.socket.on('functionResponse', (dataArg: ISocketRequestDataObject) => {
plugins.beautylog.info(`received response for request with id ${dataArg.shortId}`)
let targetSocketRequest = helpers.getSocketRequestById(dataArg.shortId)
targetSocketRequest.handleResponse(dataArg)
})
plugins.beautylog.log(`now listening to function requests for ${this.alias}`)
done.resolve(this)
} else {
let errMessage: 'socket needs to be authenticated first'
plugins.beautylog.error(errMessage)
done.reject(errMessage)
}
return done.promise
}
// sending ----------------------
};
// sending ----------------------
}

View File

@ -1,8 +1,8 @@
import * as plugins from "./smartsocket.plugins";
import * as plugins from './smartsocket.plugins'
// import classes
import { Objectmap } from "lik";
import { SocketRole } from "./smartsocket.classes.socketrole";
import { Objectmap } from 'lik'
import { SocketRole } from './smartsocket.classes.socketrole'
// export interfaces
@ -10,28 +10,28 @@ import { SocketRole } from "./smartsocket.classes.socketrole";
* interface of the contructor options of class SocketFunction
*/
export interface ISocketFunctionConstructorOptions {
funcName: string;
funcDef: any;
allowedRoles: SocketRole[]; // all roles that are allowed to execute a SocketFunction
};
funcName: string
funcDef: any
allowedRoles: SocketRole[] // all roles that are allowed to execute a SocketFunction
}
/**
* interface of the Socket Function call, in other words the object that routes a call to a function
*/
export interface ISocketFunctionCall {
funcName:string;
funcDataArg:any;
};
funcName: string
funcDataArg: any
}
/**
* interface for function definition of SocketFunction
*/
export interface IFuncDef {
(dataArg:any):PromiseLike<any>
(dataArg: any): PromiseLike<any>
}
// export objects
export let allSocketFunctions = new Objectmap<SocketFunction>();
export let allSocketFunctions = new Objectmap<SocketFunction>()
// export classes
@ -39,49 +39,48 @@ export let allSocketFunctions = new Objectmap<SocketFunction>();
* class that respresents a function that can be transparently called using a SocketConnection
*/
export class SocketFunction {
name: string;
funcDef: IFuncDef;
roles: SocketRole[];
name: string
funcDef: IFuncDef
roles: SocketRole[]
/**
* the constructor for SocketFunction
*/
constructor(optionsArg: ISocketFunctionConstructorOptions) {
this.name = optionsArg.funcName;
this.funcDef = optionsArg.funcDef;
this.roles = optionsArg.allowedRoles;
for (let socketRoleArg of this.roles){
this._notifyRole(socketRoleArg);
};
allSocketFunctions.add(this); // map instance with Objectmap
};
/**
* notifies a role about access to this SocketFunction
*/
private _notifyRole(socketRoleArg:SocketRole){
socketRoleArg.addSocketFunction(this);
/**
* the constructor for SocketFunction
*/
constructor (optionsArg: ISocketFunctionConstructorOptions) {
this.name = optionsArg.funcName
this.funcDef = optionsArg.funcDef
this.roles = optionsArg.allowedRoles
for (let socketRoleArg of this.roles) {
this._notifyRole(socketRoleArg)
}
/**
* invokes the function of this SocketFunction
*/
invoke(dataArg:ISocketFunctionCall):plugins.q.Promise<any> {
let done = plugins.q.defer();
if(dataArg.funcName === this.name){
this.funcDef(dataArg.funcDataArg)
.then((resultData:any) => {
let funcResponseData:ISocketFunctionCall = {
funcName:this.name,
funcDataArg:resultData
}
done.resolve(funcResponseData);
});
} else {
throw new Error("SocketFunction.name does not match the data argument's .name!");
}
return done.promise;
};
allSocketFunctions.add(this) // map instance with Objectmap
}
}
/**
* invokes the function of this SocketFunction
*/
invoke (dataArg: ISocketFunctionCall): Promise<any> {
let done = plugins.smartq.defer()
if (dataArg.funcName === this.name) {
this.funcDef(dataArg.funcDataArg)
.then((resultData: any) => {
let funcResponseData: ISocketFunctionCall = {
funcName: this.name,
funcDataArg: resultData
}
done.resolve(funcResponseData)
})
} else {
throw new Error("SocketFunction.name does not match the data argument's .name!")
}
return done.promise
}
/**
* notifies a role about access to this SocketFunction
*/
private _notifyRole (socketRoleArg: SocketRole) {
socketRoleArg.addSocketFunction(this)
}
}

View File

@ -1,96 +1,96 @@
import * as plugins from "./smartsocket.plugins";
import * as helpers from "./smartsocket.helpers";
import * as plugins from './smartsocket.plugins'
import * as helpers from './smartsocket.helpers'
// import interfaces
import { ISocketFunctionCall } from "./smartsocket.classes.socketfunction";
import { ISocketFunctionCall } from './smartsocket.classes.socketfunction'
// import classes
import { Objectmap } from "lik";
import { SocketFunction } from "./smartsocket.classes.socketfunction";
import { SocketConnection } from "./smartsocket.classes.socketconnection";
import { Objectmap } from 'lik'
import { SocketFunction } from './smartsocket.classes.socketfunction'
import { SocketConnection } from './smartsocket.classes.socketconnection'
// export interfaces
export type TSocketRequestStatus = "new" | "pending" | "finished";
export type TSocketRequestSide = "requesting" | "responding";
export type TSocketRequestStatus = 'new' | 'pending' | 'finished'
export type TSocketRequestSide = 'requesting' | 'responding'
/**
* interface of constructor of class SocketRequest
*/
export interface SocketRequestConstructorOptions {
side: TSocketRequestSide;
originSocketConnection: SocketConnection;
shortId: string;
funcCallData?: ISocketFunctionCall;
};
side: TSocketRequestSide
originSocketConnection: SocketConnection
shortId: string
funcCallData?: ISocketFunctionCall
}
/**
* request object that is sent initially and may or may not receive a response
*/
export interface ISocketRequestDataObject {
funcCallData: ISocketFunctionCall;
shortId: string;
responseTimeout?: number;
};
funcCallData: ISocketFunctionCall
shortId: string
responseTimeout?: number
}
//export objects
export let allSocketRequests = new Objectmap<SocketRequest>();
// export objects
export let allSocketRequests = new Objectmap<SocketRequest>()
// export classes
export class SocketRequest {
status: TSocketRequestStatus = "new";
side: TSocketRequestSide;
shortid: string;
originSocketConnection: SocketConnection;
funcCallData: ISocketFunctionCall
done = plugins.q.defer();
constructor(optionsArg: SocketRequestConstructorOptions) {
this.side = optionsArg.side;
this.shortid = optionsArg.shortId;
this.funcCallData = optionsArg.funcCallData;
this.originSocketConnection = optionsArg.originSocketConnection;
allSocketRequests.add(this);
};
status: TSocketRequestStatus = 'new'
side: TSocketRequestSide
shortid: string
originSocketConnection: SocketConnection
funcCallData: ISocketFunctionCall
done = plugins.smartq.defer()
constructor (optionsArg: SocketRequestConstructorOptions) {
this.side = optionsArg.side
this.shortid = optionsArg.shortId
this.funcCallData = optionsArg.funcCallData
this.originSocketConnection = optionsArg.originSocketConnection
allSocketRequests.add(this)
}
// requesting --------------------------
// requesting --------------------------
/**
* dispatches a socketrequest from the requesting to the receiving side
*/
dispatch() {
/**
* dispatches a socketrequest from the requesting to the receiving side
*/
dispatch () {
let requestData: ISocketRequestDataObject = {
funcCallData: this.funcCallData,
shortId: this.shortid
}
this.originSocketConnection.socket.emit('function', requestData)
return this.done.promise
}
/**
* handles the response that is received by the requesting side
*/
handleResponse (responseDataArg: ISocketRequestDataObject) {
plugins.beautylog.log('handling response!')
this.done.resolve(responseDataArg.funcCallData)
allSocketRequests.remove(this)
}
// responding --------------------------
/**
* creates the response on the responding side
*/
createResponse () {
let targetSocketFunction: SocketFunction = helpers.getSocketFunctionByName(this.funcCallData.funcName)
plugins.beautylog.info(`invoking ${targetSocketFunction.name}`)
targetSocketFunction.invoke(this.funcCallData)
.then((resultData) => {
plugins.beautylog.log('got resultData. Sending it to requesting party.')
let requestData: ISocketRequestDataObject = {
funcCallData: this.funcCallData,
shortId: this.shortid
funcCallData: resultData,
shortId: this.shortid
}
this.originSocketConnection.socket.emit("function", requestData);
return this.done.promise;
};
/**
* handles the response that is received by the requesting side
*/
handleResponse(responseDataArg: ISocketRequestDataObject) {
plugins.beautylog.log("handling response!");
this.done.resolve(responseDataArg.funcCallData);
allSocketRequests.remove(this);
}
// responding --------------------------
/**
* creates the response on the responding side
*/
createResponse() {
let targetSocketFunction: SocketFunction = helpers.getSocketFunctionByName(this.funcCallData.funcName);
plugins.beautylog.info(`invoking ${targetSocketFunction.name}`);
targetSocketFunction.invoke(this.funcCallData)
.then((resultData) => {
plugins.beautylog.log("got resultData. Sending it to requesting party.")
let requestData: ISocketRequestDataObject = {
funcCallData: resultData,
shortId: this.shortid
};
this.originSocketConnection.socket.emit("functionResponse",requestData);
allSocketRequests.remove(this);
});
}
};
this.originSocketConnection.socket.emit('functionResponse', requestData)
allSocketRequests.remove(this)
})
}
}

View File

@ -1,9 +1,9 @@
import "typings-global";
export import beautylog = require("beautylog");
export import lik = require("lik");
export import nodehash = require("nodehash");
export import q = require("q");
export import shortid = require("shortid");
export import socketIo = require("socket.io");
export import socketIoClient = require("socket.io-client");
export import taskbuffer = require("taskbuffer");
import 'typings-global'
export import beautylog = require('beautylog')
export import lik = require('lik')
export import nodehash = require('nodehash')
export import smartq = require('smartq')
export import shortid = require('shortid')
export import socketIo = require('socket.io')
export import socketIoClient = require('socket.io-client')
export import taskbuffer = require('taskbuffer')