fix
This commit is contained in:
Vendored
-19
File diff suppressed because one or more lines are too long
+2
-9
@@ -1,12 +1,5 @@
|
||||
import { Socket } from "../backend/RPCSocketServer";
|
||||
/**
|
||||
* Dynamic library to communicate with FrontblockService remotely
|
||||
*
|
||||
* This will be automatically injected into the webpages served by FrontblockService
|
||||
* Will ask it's service for available RPCs and parse them into methods of this object
|
||||
* for convenient access.
|
||||
*/
|
||||
export declare class RPCSocket implements Socket {
|
||||
import { Socket } from './interfaces/Socket';
|
||||
export declare class Client implements Socket {
|
||||
port: number;
|
||||
private server;
|
||||
private tls;
|
||||
@@ -5,14 +5,7 @@ var bsock = require('bsock');
|
||||
function stripAfterEquals(str) {
|
||||
return str.split("=")[0];
|
||||
}
|
||||
/**
|
||||
* Dynamic library to communicate with FrontblockService remotely
|
||||
*
|
||||
* This will be automatically injected into the webpages served by FrontblockService
|
||||
* Will ask it's service for available RPCs and parse them into methods of this object
|
||||
* for convenient access.
|
||||
*/
|
||||
class RPCSocket {
|
||||
class Client {
|
||||
constructor(port, server, tls = false) {
|
||||
this.port = port;
|
||||
this.server = server;
|
||||
@@ -45,13 +38,13 @@ class RPCSocket {
|
||||
info.forEach(i => {
|
||||
let f;
|
||||
switch (i.type) {
|
||||
case 'call':
|
||||
case 'Call':
|
||||
f = this.callGenerator(i.uniqueName, i.argNames);
|
||||
break;
|
||||
case 'hook':
|
||||
case 'Hook':
|
||||
f = this.hookGenerator(i.uniqueName, i.argNames);
|
||||
break;
|
||||
case 'unhook':
|
||||
case 'Unhook':
|
||||
f = this.unhookGenerator(i.uniqueName, i.argNames);
|
||||
break;
|
||||
}
|
||||
@@ -92,4 +85,4 @@ class RPCSocket {
|
||||
} )()`);
|
||||
}
|
||||
}
|
||||
exports.RPCSocket = RPCSocket;
|
||||
exports.Client = Client;
|
||||
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
export declare type Outcome = "Success" | "Error";
|
||||
export declare class Response {
|
||||
message?: string | undefined;
|
||||
constructor(message?: string | undefined);
|
||||
}
|
||||
export declare class SuccessResponse extends Response {
|
||||
result: Outcome;
|
||||
constructor(message?: string);
|
||||
}
|
||||
export declare class ErrorResponse extends Response {
|
||||
result: Outcome;
|
||||
constructor(message?: string);
|
||||
}
|
||||
export declare class SubscriptionResponse extends SuccessResponse {
|
||||
uid: string;
|
||||
constructor(uid: string, message?: string);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
/* Responses */
|
||||
class Response {
|
||||
constructor(message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
exports.Response = Response;
|
||||
class SuccessResponse extends Response {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.result = "Success";
|
||||
}
|
||||
}
|
||||
exports.SuccessResponse = SuccessResponse;
|
||||
class ErrorResponse extends Response {
|
||||
constructor(message = "Unknown error") {
|
||||
super(message);
|
||||
this.result = "Error";
|
||||
}
|
||||
}
|
||||
exports.ErrorResponse = ErrorResponse;
|
||||
class SubscriptionResponse extends SuccessResponse {
|
||||
constructor(uid, message) {
|
||||
super(message);
|
||||
this.uid = uid;
|
||||
}
|
||||
}
|
||||
exports.SubscriptionResponse = SubscriptionResponse;
|
||||
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
import { SocketConf } from './Types';
|
||||
import { Exporter } from './interfaces/Exporter';
|
||||
import { Socket } from "./interfaces/Socket";
|
||||
export declare class Server {
|
||||
private port;
|
||||
private rpcExporters;
|
||||
private conf;
|
||||
private io;
|
||||
private wsServer;
|
||||
constructor(port: number, rpcExporters?: Exporter[], conf?: SocketConf);
|
||||
private startWebsocket;
|
||||
protected initRPCs(socket: Socket): void;
|
||||
protected initPublicRPCs(socket: Socket): void;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const http = require("http");
|
||||
const bsock = require("bsock");
|
||||
const Util_1 = require("./Util");
|
||||
class Server {
|
||||
constructor(port, rpcExporters = [], conf = {
|
||||
errorHandler: (socket) => (error) => { socket.destroy(); console.error(error); },
|
||||
closeHandler: (socket) => () => { console.log("Socket closing"); },
|
||||
connectionHandler: (socket) => { console.log("New websocket connection in port " + socket.port); },
|
||||
visibility: "127.0.0.1"
|
||||
}) {
|
||||
this.port = port;
|
||||
this.rpcExporters = rpcExporters;
|
||||
this.conf = conf;
|
||||
this.io = bsock.createServer();
|
||||
this.wsServer = http.createServer();
|
||||
this.startWebsocket();
|
||||
}
|
||||
startWebsocket() {
|
||||
try {
|
||||
this.io.attach(this.wsServer);
|
||||
this.io.on('socket', (socket) => {
|
||||
socket.on('error', this.conf.errorHandler(socket));
|
||||
socket.on('close', this.conf.closeHandler(socket));
|
||||
if (this.conf.visibility === "127.0.0.1")
|
||||
this.initRPCs(socket);
|
||||
else
|
||||
this.initPublicRPCs(socket);
|
||||
});
|
||||
this.wsServer.listen(this.port, this.conf.visibility);
|
||||
}
|
||||
catch (e) {
|
||||
//@ts-ignore
|
||||
this.errorHandler(undefined)("Unable to connect to socket");
|
||||
}
|
||||
}
|
||||
initRPCs(socket) {
|
||||
const infoRPC = [
|
||||
{
|
||||
name: 'info',
|
||||
type: 'Call',
|
||||
func: async () => rpcInfos
|
||||
}
|
||||
];
|
||||
const rpcInfos = [
|
||||
...Util_1.rpcHooker(socket, "RPC", infoRPC, false),
|
||||
...this.rpcExporters.flatMap(exporter => Util_1.rpcHooker(socket, exporter.name, [...exporter.exportPublicRPCs(), ...exporter.exportRPCs()]))
|
||||
];
|
||||
}
|
||||
initPublicRPCs(socket) {
|
||||
const rpcInfos = [
|
||||
...Util_1.rpcHooker(socket, "Admin", adminRPCs, false),
|
||||
...this.rpcExporters.flatMap(exporter => Util_1.rpcHooker(socket, exporter.name, exporter.exportPublicRPCs()))
|
||||
];
|
||||
}
|
||||
}
|
||||
exports.Server = Server;
|
||||
Vendored
+54
@@ -0,0 +1,54 @@
|
||||
import { SuccessResponse, ErrorResponse, SubscriptionResponse } from "./Response";
|
||||
import { Socket } from "./interfaces/Socket";
|
||||
export declare type Visibility = "127.0.0.1" | "0.0.0.0";
|
||||
export declare type Name = string;
|
||||
export declare type SocketConf = {
|
||||
connectionHandler: (socket: Socket) => void;
|
||||
errorHandler: (socket: Socket) => (error: any) => void;
|
||||
closeHandler: (socket: Socket) => () => void;
|
||||
visibility: Visibility;
|
||||
};
|
||||
export declare type rpcType = 'Hook' | 'Unhook' | 'Call';
|
||||
export declare type BaseRPC = {
|
||||
type: rpcType;
|
||||
name: string;
|
||||
};
|
||||
export declare type HookRPC = BaseRPC & {
|
||||
type: 'Hook';
|
||||
func: CallbackFunction;
|
||||
unhook: UnhookFunction;
|
||||
};
|
||||
export declare type UnhookRPC = BaseRPC & {
|
||||
type: 'Unhook';
|
||||
func: UnhookFunction;
|
||||
};
|
||||
export declare type CallRPC = BaseRPC & {
|
||||
type: 'Call';
|
||||
func: (...args: any[]) => Promise<any>;
|
||||
};
|
||||
export declare type SocketioRPC = CallRPC | UnhookRPC | HookRPC;
|
||||
export declare type BaseInfo = {
|
||||
owner: string;
|
||||
argNames: string[];
|
||||
};
|
||||
export declare type HookInfo = BaseRPC & BaseInfo & {
|
||||
type: 'Hook';
|
||||
generator: (socket: any) => CallbackFunction;
|
||||
unhook: UnhookFunction;
|
||||
};
|
||||
export declare type UnhookInfo = BaseRPC & BaseInfo & {
|
||||
type: 'Unhook';
|
||||
func: UnhookFunction;
|
||||
};
|
||||
export declare type CallInfo = BaseRPC & BaseInfo & {
|
||||
type: 'Call';
|
||||
func: AsyncFunction;
|
||||
};
|
||||
export declare type RpcInfo = HookInfo | UnhookInfo | CallInfo;
|
||||
export declare type ExtendedRpcInfo = RpcInfo & {
|
||||
uniqueName: string;
|
||||
};
|
||||
export declare type OnFunction = (type: 'error' | 'close', f: (e?: any) => void) => Socket;
|
||||
export declare type UnhookFunction = (uid: string) => Promise<SuccessResponse | ErrorResponse>;
|
||||
export declare type CallbackFunction = (...args: any[]) => Promise<SubscriptionResponse | ErrorResponse>;
|
||||
export declare type AsyncFunction = (...args: any[]) => Promise<any>;
|
||||
@@ -0,0 +1,2 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
import { SocketioRPC, RpcInfo, ExtendedRpcInfo } from "./Types";
|
||||
import { Socket } from "./interfaces/Socket";
|
||||
export declare const rpcToRpcinfo: (rpc: SocketioRPC, owner: string) => RpcInfo;
|
||||
export declare const rpcHooker: (socket: Socket, owner: string, RPCs: SocketioRPC[], makeUnique?: boolean) => ExtendedRpcInfo[];
|
||||
@@ -0,0 +1,75 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const uuid = require("uuid/v4");
|
||||
exports.rpcToRpcinfo = (rpc, owner) => {
|
||||
switch (rpc.type) {
|
||||
case "Call":
|
||||
return {
|
||||
owner: owner,
|
||||
argNames: extractArgs(rpc.func),
|
||||
type: rpc.type,
|
||||
name: rpc.name,
|
||||
func: rpc.func,
|
||||
};
|
||||
case "Unhook":
|
||||
return {
|
||||
owner: owner,
|
||||
argNames: extractArgs(rpc.func),
|
||||
type: rpc.type,
|
||||
name: rpc.name,
|
||||
func: rpc.func,
|
||||
};
|
||||
case "Hook":
|
||||
const generator = hookGenerator(rpc);
|
||||
return {
|
||||
owner: owner,
|
||||
argNames: extractArgs(generator(undefined)),
|
||||
type: rpc.type,
|
||||
name: rpc.name,
|
||||
unhook: rpc.unhook,
|
||||
generator: generator,
|
||||
};
|
||||
}
|
||||
};
|
||||
exports.rpcHooker = (socket, owner, RPCs, makeUnique = true) => {
|
||||
const suffix = makeUnique ? "-" + uuid().substr(0, 4) : "";
|
||||
return RPCs.map(rpc => exports.rpcToRpcinfo(rpc, owner))
|
||||
.map(info => {
|
||||
const ret = info;
|
||||
ret.uniqueName = info.name + suffix;
|
||||
switch (info.type) {
|
||||
case "Hook":
|
||||
socket.hook(ret.uniqueName, info.generator(socket));
|
||||
break;
|
||||
default:
|
||||
socket.hook(ret.uniqueName, info.func);
|
||||
}
|
||||
socket.on('close', () => socket.unhook(info.name));
|
||||
return ret;
|
||||
});
|
||||
};
|
||||
const hookGenerator = (rpc) => {
|
||||
const argsArr = extractArgs(rpc.func);
|
||||
argsArr.pop();
|
||||
const args = argsArr.join(',');
|
||||
return eval(`(socket) => async (` + args + `) => {
|
||||
const res = await rpc.func(` + args + (args.length !== 0 ? ',' : '') + ` (x) => {
|
||||
socket.call(res.uid, x)
|
||||
})
|
||||
if(res.result == 'Success'){
|
||||
socket.on('close', async () => {
|
||||
const unhookRes = await rpc.unhook(res.uid)
|
||||
console.log("Specific close handler for", rpc.name, res.uid, unhookRes)
|
||||
})
|
||||
|
||||
}
|
||||
return res
|
||||
}`);
|
||||
};
|
||||
const extractArgs = (f) => {
|
||||
let fn = String(f);
|
||||
let args = fn.substr(0, fn.indexOf(")"));
|
||||
args = args.substr(fn.indexOf("(") + 1);
|
||||
let ret = args.split(",");
|
||||
return ret;
|
||||
};
|
||||
Vendored
-98
@@ -1,98 +0,0 @@
|
||||
import { Socket } from "./RPCSocketServer";
|
||||
declare type rpcType = 'hook' | 'unhook' | 'call';
|
||||
export declare type Outcome = "Success" | "Error";
|
||||
export declare type Visibility = "127.0.0.1" | "0.0.0.0";
|
||||
export declare class Response {
|
||||
message?: string | undefined;
|
||||
constructor(message?: string | undefined);
|
||||
}
|
||||
export declare class SuccessResponse extends Response {
|
||||
result: Outcome;
|
||||
constructor(message?: string);
|
||||
}
|
||||
export declare class ErrorResponse extends Response {
|
||||
result: Outcome;
|
||||
constructor(message?: string);
|
||||
}
|
||||
export declare class SubscriptionResponse extends SuccessResponse {
|
||||
uid: string;
|
||||
constructor(uid: string, message?: string);
|
||||
}
|
||||
export declare type UnhookFunction = (uid: string) => Promise<SuccessResponse | ErrorResponse>;
|
||||
export declare type callbackFunction = (...args: any[]) => Promise<SubscriptionResponse | ErrorResponse>;
|
||||
export declare type AsyncFunction = (...args: any[]) => Promise<any>;
|
||||
export interface RPCExporter {
|
||||
name: string;
|
||||
exportRPCs(): socketioRPC[];
|
||||
exportPublicRPCs(): socketioRPC[];
|
||||
}
|
||||
declare type baseRPC = {
|
||||
type: rpcType;
|
||||
name: string;
|
||||
};
|
||||
declare type hookRPC = baseRPC & {
|
||||
type: 'hook';
|
||||
func: callbackFunction;
|
||||
unhook: UnhookFunction;
|
||||
};
|
||||
declare type unhookRPC = baseRPC & {
|
||||
type: 'unhook';
|
||||
func: UnhookFunction;
|
||||
};
|
||||
declare type callRPC = baseRPC & {
|
||||
type: 'call';
|
||||
func: (...args: any[]) => Promise<any>;
|
||||
};
|
||||
export declare type socketioRPC = callRPC | unhookRPC | hookRPC;
|
||||
export declare type baseInfo = {
|
||||
owner: string;
|
||||
argNames: string[];
|
||||
};
|
||||
declare type HookInfo = baseRPC & baseInfo & {
|
||||
type: 'hook';
|
||||
generator: (socket: any) => callbackFunction;
|
||||
unhook: UnhookFunction;
|
||||
};
|
||||
declare type UnhookInfo = baseRPC & baseInfo & {
|
||||
type: 'unhook';
|
||||
func: UnhookFunction;
|
||||
};
|
||||
declare type CallInfo = baseRPC & baseInfo & {
|
||||
type: 'call';
|
||||
func: AsyncFunction;
|
||||
};
|
||||
declare type RpcInfo = HookInfo | UnhookInfo | CallInfo;
|
||||
export declare type ExtendedRpcInfo = RpcInfo & {
|
||||
uniqueName: string;
|
||||
};
|
||||
export declare const rpcToRpcinfo: (rpc: socketioRPC, owner: string) => RpcInfo;
|
||||
export declare const rpcHooker: (socket: Socket, owner: string, RPCs: socketioRPC[], makeUnique?: boolean) => ExtendedRpcInfo[];
|
||||
declare type OnFunction = (type: 'error' | 'close', f: (e?: any) => void) => Socket;
|
||||
export interface Socket {
|
||||
port: number;
|
||||
hook: (rpcname: string, ...args: any[]) => Socket;
|
||||
unhook: (rpcname: string) => Socket;
|
||||
call: (rpcname: string, ...args: any[]) => Promise<any>;
|
||||
fire: (rpcname: string, ...args: any[]) => Promise<any>;
|
||||
on: OnFunction;
|
||||
destroy: () => void;
|
||||
close: () => void;
|
||||
}
|
||||
export declare type RPCSocketConf = {
|
||||
connectionHandler: (socket: Socket) => void;
|
||||
errorHandler: (socket: Socket) => (error: any) => void;
|
||||
closeHandler: (socket: Socket) => () => void;
|
||||
};
|
||||
export declare class RPCSocketServer {
|
||||
private port;
|
||||
private rpcExporters;
|
||||
private visibility;
|
||||
private conf;
|
||||
private io;
|
||||
private wsServer;
|
||||
constructor(port: number, rpcExporters?: RPCExporter[], visibility?: Visibility, conf?: RPCSocketConf);
|
||||
private startWebsocket;
|
||||
protected initApis(socket: Socket): void;
|
||||
protected initPublicApis(socket: Socket): void;
|
||||
}
|
||||
export {};
|
||||
@@ -1,165 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const http = require("http");
|
||||
const bsock = require("bsock");
|
||||
const uuid = require("uuid/v4");
|
||||
/* Responses */
|
||||
class Response {
|
||||
constructor(message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
exports.Response = Response;
|
||||
class SuccessResponse extends Response {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.result = "Success";
|
||||
}
|
||||
}
|
||||
exports.SuccessResponse = SuccessResponse;
|
||||
class ErrorResponse extends Response {
|
||||
constructor(message = "Unknown error") {
|
||||
super(message);
|
||||
this.result = "Error";
|
||||
}
|
||||
}
|
||||
exports.ErrorResponse = ErrorResponse;
|
||||
class SubscriptionResponse extends SuccessResponse {
|
||||
constructor(uid, message) {
|
||||
super(message);
|
||||
this.uid = uid;
|
||||
}
|
||||
}
|
||||
exports.SubscriptionResponse = SubscriptionResponse;
|
||||
exports.rpcToRpcinfo = (rpc, owner) => {
|
||||
switch (rpc.type) {
|
||||
case "call":
|
||||
return {
|
||||
owner: owner,
|
||||
argNames: extractArgs(rpc.func),
|
||||
type: rpc.type,
|
||||
name: rpc.name,
|
||||
func: rpc.func,
|
||||
};
|
||||
case "unhook":
|
||||
return {
|
||||
owner: owner,
|
||||
argNames: extractArgs(rpc.func),
|
||||
type: rpc.type,
|
||||
name: rpc.name,
|
||||
func: rpc.func,
|
||||
};
|
||||
case "hook":
|
||||
const generator = hookGenerator(rpc);
|
||||
return {
|
||||
owner: owner,
|
||||
argNames: extractArgs(generator(undefined)),
|
||||
type: rpc.type,
|
||||
name: rpc.name,
|
||||
unhook: rpc.unhook,
|
||||
generator: generator,
|
||||
};
|
||||
}
|
||||
};
|
||||
exports.rpcHooker = (socket, owner, RPCs, makeUnique = true) => {
|
||||
const suffix = makeUnique ? "-" + uuid().substr(0, 4) : "";
|
||||
return RPCs.map(rpc => exports.rpcToRpcinfo(rpc, owner))
|
||||
.map(info => {
|
||||
const ret = info;
|
||||
ret.uniqueName = info.name + suffix;
|
||||
switch (info.type) {
|
||||
case "hook":
|
||||
socket.hook(ret.uniqueName, info.generator(socket));
|
||||
break;
|
||||
default:
|
||||
socket.hook(ret.uniqueName, info.func);
|
||||
}
|
||||
socket.on('close', () => socket.unhook(info.name));
|
||||
return ret;
|
||||
});
|
||||
};
|
||||
const hookGenerator = (rpc) => {
|
||||
const argsArr = extractArgs(rpc.func);
|
||||
argsArr.pop();
|
||||
const args = argsArr.join(',');
|
||||
return eval(`(socket) => async (` + args + `) => {
|
||||
const res = await rpc.func(` + args + (args.length !== 0 ? ',' : '') + ` (x) => {
|
||||
socket.call(res.uid, x)
|
||||
})
|
||||
if(res.result == 'Success'){
|
||||
socket.on('close', async () => {
|
||||
const unhookRes = await rpc.unhook(res.uid)
|
||||
console.log("Specific close handler for", rpc.name, res.uid, unhookRes)
|
||||
})
|
||||
|
||||
}
|
||||
return res
|
||||
}`);
|
||||
};
|
||||
const extractArgs = (f) => {
|
||||
let fn = String(f);
|
||||
let args = fn.substr(0, fn.indexOf(")"));
|
||||
args = args.substr(fn.indexOf("(") + 1);
|
||||
let ret = args.split(",");
|
||||
return ret;
|
||||
};
|
||||
class RPCSocketServer {
|
||||
constructor(port, rpcExporters = [], visibility = "127.0.0.1", conf = {
|
||||
errorHandler: (socket) => (error) => { socket.destroy(); console.error(error); },
|
||||
closeHandler: (socket) => () => { console.log("Socket closing"); },
|
||||
connectionHandler: (socket) => { console.log("New websocket connection in port " + socket.port); }
|
||||
}) {
|
||||
this.port = port;
|
||||
this.rpcExporters = rpcExporters;
|
||||
this.visibility = visibility;
|
||||
this.conf = conf;
|
||||
this.io = bsock.createServer();
|
||||
this.wsServer = http.createServer();
|
||||
this.startWebsocket();
|
||||
}
|
||||
startWebsocket() {
|
||||
try {
|
||||
this.io.attach(this.wsServer);
|
||||
this.io.on('socket', (socket) => {
|
||||
socket.on('error', this.conf.errorHandler(socket));
|
||||
socket.on('close', this.conf.closeHandler(socket));
|
||||
if (this.visibility === "127.0.0.1")
|
||||
this.initApis(socket);
|
||||
else
|
||||
this.initPublicApis(socket);
|
||||
});
|
||||
this.wsServer.listen(this.port, this.visibility);
|
||||
}
|
||||
catch (e) {
|
||||
//@ts-ignore
|
||||
this.errorHandler(undefined)("Unable to connect to socket");
|
||||
}
|
||||
}
|
||||
initApis(socket) {
|
||||
const adminRPCs = [
|
||||
{
|
||||
name: 'info',
|
||||
type: 'call',
|
||||
func: async () => rpcInfos
|
||||
}
|
||||
];
|
||||
const rpcInfos = [
|
||||
...exports.rpcHooker(socket, "Admin", adminRPCs, false),
|
||||
...this.rpcExporters.flatMap(exporter => exports.rpcHooker(socket, exporter.name, [...exporter.exportPublicRPCs(), ...exporter.exportRPCs()]))
|
||||
];
|
||||
}
|
||||
initPublicApis(socket) {
|
||||
const adminRPCs = [
|
||||
{
|
||||
name: 'info',
|
||||
type: 'call',
|
||||
func: async () => rpcInfos
|
||||
}
|
||||
];
|
||||
const rpcInfos = [
|
||||
...exports.rpcHooker(socket, "Admin", adminRPCs, false),
|
||||
...this.rpcExporters.flatMap(exporter => exports.rpcHooker(socket, exporter.name, exporter.exportPublicRPCs()))
|
||||
];
|
||||
}
|
||||
}
|
||||
exports.RPCSocketServer = RPCSocketServer;
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
import { SocketioRPC, Name } from "../Types";
|
||||
export interface Exporter {
|
||||
name: Name;
|
||||
exportRPCs(): SocketioRPC[];
|
||||
exportPublicRPCs(): SocketioRPC[];
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
import { OnFunction } from "../Types";
|
||||
export interface Socket {
|
||||
port: number;
|
||||
hook: (rpcname: string, ...args: any[]) => Socket;
|
||||
unhook: (rpcname: string) => Socket;
|
||||
call: (rpcname: string, ...args: any[]) => Promise<any>;
|
||||
fire: (rpcname: string, ...args: any[]) => Promise<any>;
|
||||
on: OnFunction;
|
||||
destroy: () => void;
|
||||
close: () => void;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
+5
-5
@@ -1,9 +1,9 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const RPCSocketServer_1 = require("../src/backend/RPCSocketServer");
|
||||
const Server_1 = require("../src/Server");
|
||||
//@ts-ignore
|
||||
const RPCSocket_1 = require("../src/frontend/RPCSocket");
|
||||
new RPCSocketServer_1.RPCSocketServer(20000, [{
|
||||
const Client_1 = require("../src/Client");
|
||||
new Server_1.Server(20000, [{
|
||||
name: "HelloWorldRPCGroup",
|
||||
exportPublicRPCs: () => [],
|
||||
exportRPCs: () => [{
|
||||
@@ -11,8 +11,8 @@ new RPCSocketServer_1.RPCSocketServer(20000, [{
|
||||
name: 'echo',
|
||||
func: async (s) => s,
|
||||
}],
|
||||
}], "0.0.0.0");
|
||||
const caller = new RPCSocket_1.RPCSocket(20000, 'localhost');
|
||||
}]);
|
||||
const caller = new Client_1.Client(20000, 'localhost');
|
||||
caller.connect().then(_ => {
|
||||
caller.info().then(console.log);
|
||||
caller["HelloWorldRPCGroup"].echo("x").then(console.log);
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
"scripts": {
|
||||
"build": "npm run clean; npm run tsc; npm run webpack",
|
||||
"tsc": "tsc",
|
||||
"webpack": "webpack --config src/frontend/webpack.prod.js --progress --colors",
|
||||
"webpack": "webpack --config src/webpack.prod.js --progress --colors",
|
||||
"clean": "rm -rf lib"
|
||||
},
|
||||
"author": "",
|
||||
|
||||
@@ -1,20 +1,14 @@
|
||||
import { ExtendedRpcInfo, UnhookFunction, callbackFunction, AsyncFunction, Socket } from "../backend/RPCSocketServer";
|
||||
var bsock = require('bsock')
|
||||
|
||||
import { ExtendedRpcInfo, UnhookFunction, CallbackFunction, AsyncFunction } from "./Types";
|
||||
import { Socket } from './interfaces/Socket'
|
||||
|
||||
//fix args with defaults like "force = true" -> "force"
|
||||
function stripAfterEquals(str:string){
|
||||
return str.split("=")[0]
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Dynamic library to communicate with FrontblockService remotely
|
||||
*
|
||||
* This will be automatically injected into the webpages served by FrontblockService
|
||||
* Will ask it's service for available RPCs and parse them into methods of this object
|
||||
* for convenient access.
|
||||
*/
|
||||
export class RPCSocket implements Socket{
|
||||
export class Client implements Socket{
|
||||
private socket: Socket
|
||||
constructor(public port:number, private server: string, private tls: boolean = false){
|
||||
}
|
||||
@@ -54,13 +48,13 @@ export class RPCSocket implements Socket{
|
||||
info.forEach(i => {
|
||||
let f: any
|
||||
switch (i.type) {
|
||||
case 'call':
|
||||
case 'Call':
|
||||
f = this.callGenerator(i.uniqueName, i.argNames)
|
||||
break
|
||||
case 'hook':
|
||||
case 'Hook':
|
||||
f = this.hookGenerator(i.uniqueName, i.argNames)
|
||||
break
|
||||
case 'unhook':
|
||||
case 'Unhook':
|
||||
f = this.unhookGenerator(i.uniqueName, i.argNames)
|
||||
break
|
||||
}
|
||||
@@ -81,7 +75,7 @@ export class RPCSocket implements Socket{
|
||||
return eval( '( () => async ('+headerArgs+') => { return await this.socket.call("'+fnName+'", '+argParams+')} )()' )
|
||||
}
|
||||
|
||||
private hookGenerator(fnName, fnArgs:string[]): callbackFunction{
|
||||
private hookGenerator(fnName, fnArgs:string[]): CallbackFunction{
|
||||
const headerArgs = fnArgs.join(",")
|
||||
const argParams = fnArgs.map(stripAfterEquals).join(",")
|
||||
return eval( `( () => async (`+headerArgs+(headerArgs.length!==0?",":"")+` callback) => {
|
||||
@@ -0,0 +1,38 @@
|
||||
|
||||
export type Outcome = "Success" | "Error"
|
||||
|
||||
/* Responses */
|
||||
export class Response{
|
||||
constructor(
|
||||
public message?:string
|
||||
){}
|
||||
}
|
||||
|
||||
export class SuccessResponse extends Response{
|
||||
result:Outcome = "Success"
|
||||
|
||||
constructor(
|
||||
message?:string
|
||||
){
|
||||
super(message)
|
||||
}
|
||||
}
|
||||
|
||||
export class ErrorResponse extends Response{
|
||||
result:Outcome = "Error"
|
||||
|
||||
constructor(
|
||||
message: string = "Unknown error"
|
||||
){
|
||||
super(message)
|
||||
}
|
||||
}
|
||||
|
||||
export class SubscriptionResponse extends SuccessResponse{
|
||||
constructor(
|
||||
public uid: string,
|
||||
message?:string
|
||||
){
|
||||
super(message)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import http = require('http');
|
||||
import bsock = require('bsock');
|
||||
|
||||
import { ExtendedRpcInfo, SocketConf, SocketioRPC } from './Types';
|
||||
import { rpcHooker } from './Util';
|
||||
import { Exporter } from './interfaces/Exporter';
|
||||
import { Socket } from "./interfaces/Socket";
|
||||
|
||||
export class Server{
|
||||
|
||||
private io = bsock.createServer()
|
||||
private wsServer = http.createServer()
|
||||
|
||||
constructor(
|
||||
private port:number,
|
||||
private rpcExporters: Exporter[] = [],
|
||||
private conf: SocketConf = {
|
||||
errorHandler: (socket:Socket) => (error:any) => { socket.destroy(); console.error(error) },
|
||||
closeHandler: (socket:Socket) => () => { console.log("Socket closing") },
|
||||
connectionHandler: (socket:Socket) => { console.log("New websocket connection in port "+socket.port)},
|
||||
visibility: "127.0.0.1"
|
||||
}
|
||||
){
|
||||
this.startWebsocket()
|
||||
}
|
||||
|
||||
private startWebsocket(){
|
||||
try{
|
||||
this.io.attach(this.wsServer)
|
||||
this.io.on('socket', (socket:Socket) => {
|
||||
socket.on('error', this.conf.errorHandler(socket))
|
||||
socket.on('close', this.conf.closeHandler(socket))
|
||||
if(this.conf.visibility === "127.0.0.1")
|
||||
this.initRPCs(socket)
|
||||
else
|
||||
this.initPublicRPCs(socket)
|
||||
})
|
||||
this.wsServer.listen(this.port, this.conf.visibility)
|
||||
}catch(e){
|
||||
//@ts-ignore
|
||||
this.errorHandler(undefined)("Unable to connect to socket")
|
||||
}
|
||||
}
|
||||
|
||||
protected initRPCs(socket:Socket){
|
||||
const infoRPC:SocketioRPC[] = [
|
||||
{
|
||||
name: 'info',
|
||||
type: 'Call',
|
||||
func: async () => rpcInfos
|
||||
}
|
||||
]
|
||||
const rpcInfos:ExtendedRpcInfo[] = [
|
||||
...rpcHooker(socket, "RPC", infoRPC, false),
|
||||
...this.rpcExporters.flatMap(exporter => rpcHooker(socket, exporter.name, [...exporter.exportPublicRPCs(), ...exporter.exportRPCs()]))
|
||||
]
|
||||
}
|
||||
|
||||
protected initPublicRPCs(socket:Socket){}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
import { SuccessResponse, ErrorResponse, SubscriptionResponse } from "./Response";
|
||||
import { Socket } from "./interfaces/Socket";
|
||||
|
||||
export type Visibility = "127.0.0.1" | "0.0.0.0"
|
||||
export type Name = string
|
||||
|
||||
export type SocketConf = {
|
||||
connectionHandler: (socket:Socket) => void
|
||||
errorHandler: (socket:Socket) => (error:any) => void
|
||||
closeHandler: (socket:Socket) => () => void
|
||||
visibility: Visibility
|
||||
}
|
||||
|
||||
export type rpcType = 'Hook' | 'Unhook' | 'Call'
|
||||
|
||||
export type BaseRPC = {
|
||||
type: rpcType
|
||||
name: string
|
||||
}
|
||||
|
||||
export type HookRPC = BaseRPC & {
|
||||
type: 'Hook'
|
||||
func: CallbackFunction
|
||||
unhook: UnhookFunction
|
||||
}
|
||||
|
||||
export type UnhookRPC = BaseRPC & {
|
||||
type: 'Unhook'
|
||||
func: UnhookFunction
|
||||
}
|
||||
|
||||
export type CallRPC = BaseRPC & {
|
||||
type: 'Call'
|
||||
func: (...args) => Promise<any>
|
||||
}
|
||||
|
||||
export type SocketioRPC = CallRPC | UnhookRPC | HookRPC
|
||||
|
||||
export type BaseInfo = {
|
||||
owner: string,
|
||||
argNames: string[],
|
||||
}
|
||||
|
||||
export type HookInfo = BaseRPC & BaseInfo & {
|
||||
type: 'Hook',
|
||||
generator: (socket) => CallbackFunction
|
||||
unhook: UnhookFunction
|
||||
}
|
||||
|
||||
export type UnhookInfo = BaseRPC & BaseInfo & {
|
||||
type: 'Unhook',
|
||||
func: UnhookFunction
|
||||
}
|
||||
|
||||
export type CallInfo = BaseRPC & BaseInfo & {
|
||||
type: 'Call',
|
||||
func: AsyncFunction
|
||||
}
|
||||
|
||||
export type RpcInfo = HookInfo | UnhookInfo | CallInfo
|
||||
export type ExtendedRpcInfo = RpcInfo & { uniqueName: string }
|
||||
|
||||
export type OnFunction = (type: 'error' | 'close', f: (e?:any)=>void) => Socket
|
||||
export type UnhookFunction = (uid:string) => Promise<SuccessResponse | ErrorResponse>
|
||||
export type CallbackFunction = (...args) => Promise<SubscriptionResponse | ErrorResponse>
|
||||
export type AsyncFunction = (...args) => Promise<any>
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
import * as uuid from "uuid/v4"
|
||||
|
||||
import { HookRPC, HookInfo, SocketioRPC, RpcInfo, ExtendedRpcInfo } from "./Types";
|
||||
import { Socket } from "./interfaces/Socket";
|
||||
|
||||
export const rpcToRpcinfo = (rpc : SocketioRPC, owner: string):RpcInfo => {
|
||||
switch(rpc.type){
|
||||
case "Call" :
|
||||
return {
|
||||
owner: owner,
|
||||
argNames: extractArgs(rpc.func),
|
||||
type: rpc.type,
|
||||
name: rpc.name,
|
||||
func: rpc.func,
|
||||
}
|
||||
case "Unhook" :
|
||||
return {
|
||||
owner: owner,
|
||||
argNames: extractArgs(rpc.func),
|
||||
type: rpc.type,
|
||||
name: rpc.name,
|
||||
func: rpc.func,
|
||||
}
|
||||
case "Hook" :
|
||||
const generator = hookGenerator(rpc)
|
||||
return {
|
||||
owner: owner,
|
||||
argNames: extractArgs(generator(undefined)),
|
||||
type: rpc.type,
|
||||
name: rpc.name,
|
||||
unhook: rpc.unhook,
|
||||
generator: generator,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const rpcHooker = (socket: Socket, owner:string, RPCs: SocketioRPC[], makeUnique = true):ExtendedRpcInfo[] => {
|
||||
const suffix = makeUnique?"-"+uuid().substr(0,4):""
|
||||
return RPCs.map(rpc => rpcToRpcinfo(rpc, owner))
|
||||
.map(info => {
|
||||
const ret:any = info
|
||||
ret.uniqueName = info.name+suffix
|
||||
|
||||
switch(info.type){
|
||||
case "Hook":
|
||||
socket.hook(ret.uniqueName, info.generator(socket))
|
||||
break;
|
||||
default:
|
||||
socket.hook(ret.uniqueName, info.func)
|
||||
}
|
||||
socket.on('close', () => socket.unhook(info.name))
|
||||
return ret
|
||||
})
|
||||
}
|
||||
|
||||
const hookGenerator = (rpc:HookRPC): HookInfo['generator'] => {
|
||||
const argsArr = extractArgs(rpc.func)
|
||||
argsArr.pop()
|
||||
const args = argsArr.join(',')
|
||||
|
||||
return eval(`(socket) => async (`+args+`) => {
|
||||
const res = await rpc.func(`+args+(args.length!==0?',':'')+` (x) => {
|
||||
socket.call(res.uid, x)
|
||||
})
|
||||
if(res.result == 'Success'){
|
||||
socket.on('close', async () => {
|
||||
const unhookRes = await rpc.unhook(res.uid)
|
||||
console.log("Specific close handler for", rpc.name, res.uid, unhookRes)
|
||||
})
|
||||
|
||||
}
|
||||
return res
|
||||
}`)
|
||||
}
|
||||
|
||||
const extractArgs = (f:Function):string[] => {
|
||||
let fn = String(f)
|
||||
let args = fn.substr(0, fn.indexOf(")"))
|
||||
args = args.substr(fn.indexOf("(")+1)
|
||||
let ret = args.split(",")
|
||||
return ret
|
||||
}
|
||||
@@ -1,267 +0,0 @@
|
||||
import http = require('http');
|
||||
import bsock = require('bsock');
|
||||
|
||||
import * as uuid from "uuid/v4"
|
||||
import { Socket } from "./RPCSocketServer"
|
||||
|
||||
type rpcType = 'hook' | 'unhook' | 'call'
|
||||
export type Outcome = "Success" | "Error"
|
||||
export type Visibility = "127.0.0.1" | "0.0.0.0"
|
||||
|
||||
/* Responses */
|
||||
export class Response{
|
||||
constructor(
|
||||
public message?:string
|
||||
){}
|
||||
}
|
||||
|
||||
export class SuccessResponse extends Response{
|
||||
result:Outcome = "Success"
|
||||
|
||||
constructor(
|
||||
message?:string
|
||||
){
|
||||
super(message)
|
||||
}
|
||||
}
|
||||
|
||||
export class ErrorResponse extends Response{
|
||||
result:Outcome = "Error"
|
||||
|
||||
constructor(
|
||||
message: string = "Unknown error"
|
||||
){
|
||||
super(message)
|
||||
}
|
||||
}
|
||||
|
||||
export class SubscriptionResponse extends SuccessResponse{
|
||||
constructor(
|
||||
public uid: string,
|
||||
message?:string
|
||||
){
|
||||
super(message)
|
||||
}
|
||||
}
|
||||
export type UnhookFunction = (uid:string) => Promise<SuccessResponse | ErrorResponse>
|
||||
export type callbackFunction = (...args) => Promise<SubscriptionResponse | ErrorResponse>
|
||||
export type AsyncFunction = (...args) => Promise<any>
|
||||
|
||||
export interface RPCExporter{
|
||||
name: string
|
||||
exportRPCs() : socketioRPC[]
|
||||
exportPublicRPCs() : socketioRPC[]
|
||||
}
|
||||
|
||||
type baseRPC = {
|
||||
type: rpcType
|
||||
name: string
|
||||
}
|
||||
|
||||
type hookRPC = baseRPC & {
|
||||
type: 'hook'
|
||||
func: callbackFunction
|
||||
unhook: UnhookFunction
|
||||
}
|
||||
|
||||
type unhookRPC = baseRPC & {
|
||||
type: 'unhook'
|
||||
func: UnhookFunction
|
||||
}
|
||||
|
||||
type callRPC = baseRPC & {
|
||||
type: 'call'
|
||||
func: (...args) => Promise<any>
|
||||
}
|
||||
|
||||
export type socketioRPC = callRPC | unhookRPC | hookRPC
|
||||
|
||||
export type baseInfo = {
|
||||
owner: string,
|
||||
argNames: string[],
|
||||
}
|
||||
|
||||
type HookInfo = baseRPC & baseInfo & {
|
||||
type: 'hook',
|
||||
generator: (socket) => callbackFunction
|
||||
unhook: UnhookFunction
|
||||
}
|
||||
|
||||
type UnhookInfo = baseRPC & baseInfo & {
|
||||
type: 'unhook',
|
||||
func: UnhookFunction
|
||||
}
|
||||
|
||||
type CallInfo = baseRPC & baseInfo & {
|
||||
type: 'call',
|
||||
func: AsyncFunction
|
||||
}
|
||||
|
||||
type RpcInfo = HookInfo | UnhookInfo | CallInfo
|
||||
|
||||
export type ExtendedRpcInfo = RpcInfo & { uniqueName: string }
|
||||
|
||||
export const rpcToRpcinfo = (rpc : socketioRPC, owner: string):RpcInfo => {
|
||||
switch(rpc.type){
|
||||
case "call" :
|
||||
return {
|
||||
owner: owner,
|
||||
argNames: extractArgs(rpc.func),
|
||||
type: rpc.type,
|
||||
name: rpc.name,
|
||||
func: rpc.func,
|
||||
}
|
||||
case "unhook" :
|
||||
return {
|
||||
owner: owner,
|
||||
argNames: extractArgs(rpc.func),
|
||||
type: rpc.type,
|
||||
name: rpc.name,
|
||||
func: rpc.func,
|
||||
}
|
||||
case "hook" :
|
||||
const generator = hookGenerator(rpc)
|
||||
return {
|
||||
owner: owner,
|
||||
argNames: extractArgs(generator(undefined)),
|
||||
type: rpc.type,
|
||||
name: rpc.name,
|
||||
unhook: rpc.unhook,
|
||||
generator: generator,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const rpcHooker = (socket: Socket, owner:string, RPCs: socketioRPC[], makeUnique = true):ExtendedRpcInfo[] => {
|
||||
const suffix = makeUnique?"-"+uuid().substr(0,4):""
|
||||
return RPCs.map(rpc => rpcToRpcinfo(rpc, owner))
|
||||
.map(info => {
|
||||
const ret:any = info
|
||||
ret.uniqueName = info.name+suffix
|
||||
|
||||
switch(info.type){
|
||||
case "hook":
|
||||
socket.hook(ret.uniqueName, info.generator(socket))
|
||||
break;
|
||||
default:
|
||||
socket.hook(ret.uniqueName, info.func)
|
||||
}
|
||||
socket.on('close', () => socket.unhook(info.name))
|
||||
return ret
|
||||
})
|
||||
}
|
||||
|
||||
const hookGenerator = (rpc:hookRPC): HookInfo['generator'] => {
|
||||
const argsArr = extractArgs(rpc.func)
|
||||
argsArr.pop()
|
||||
const args = argsArr.join(',')
|
||||
|
||||
return eval(`(socket) => async (`+args+`) => {
|
||||
const res = await rpc.func(`+args+(args.length!==0?',':'')+` (x) => {
|
||||
socket.call(res.uid, x)
|
||||
})
|
||||
if(res.result == 'Success'){
|
||||
socket.on('close', async () => {
|
||||
const unhookRes = await rpc.unhook(res.uid)
|
||||
console.log("Specific close handler for", rpc.name, res.uid, unhookRes)
|
||||
})
|
||||
|
||||
}
|
||||
return res
|
||||
}`)
|
||||
}
|
||||
|
||||
const extractArgs = (f:Function):string[] => {
|
||||
let fn = String(f)
|
||||
let args = fn.substr(0, fn.indexOf(")"))
|
||||
args = args.substr(fn.indexOf("(")+1)
|
||||
let ret = args.split(",")
|
||||
return ret
|
||||
}
|
||||
|
||||
|
||||
type OnFunction = (type: 'error' | 'close', f: (e?:any)=>void) => Socket
|
||||
|
||||
export interface Socket {
|
||||
port: number
|
||||
hook: (rpcname: string, ...args: any[]) => Socket
|
||||
unhook: (rpcname:string) => Socket
|
||||
call: (rpcname:string, ...args: any[]) => Promise<any>
|
||||
fire: (rpcname:string, ...args: any[]) => Promise<any>
|
||||
on: OnFunction
|
||||
destroy: ()=>void
|
||||
close: ()=>void
|
||||
}
|
||||
|
||||
export type RPCSocketConf = {
|
||||
connectionHandler: (socket:Socket) => void
|
||||
errorHandler: (socket:Socket) => (error:any) => void
|
||||
closeHandler: (socket:Socket) => () => void
|
||||
}
|
||||
|
||||
export class RPCSocketServer{
|
||||
|
||||
private io = bsock.createServer()
|
||||
private wsServer = http.createServer()
|
||||
|
||||
constructor(
|
||||
private port:number,
|
||||
private rpcExporters: RPCExporter[] = [],
|
||||
private visibility: Visibility = "127.0.0.1",
|
||||
private conf: RPCSocketConf = {
|
||||
errorHandler: (socket:Socket) => (error:any) => { socket.destroy(); console.error(error) },
|
||||
closeHandler: (socket:Socket) => () => { console.log("Socket closing") },
|
||||
connectionHandler: (socket:Socket) => { console.log("New websocket connection in port "+socket.port) }
|
||||
}
|
||||
){
|
||||
this.startWebsocket()
|
||||
}
|
||||
|
||||
private startWebsocket(){
|
||||
try{
|
||||
this.io.attach(this.wsServer)
|
||||
this.io.on('socket', (socket:Socket) => {
|
||||
socket.on('error', this.conf.errorHandler(socket))
|
||||
socket.on('close', this.conf.closeHandler(socket))
|
||||
if(this.visibility === "127.0.0.1")
|
||||
this.initRPCs(socket)
|
||||
else
|
||||
this.initPublicRPCs(socket)
|
||||
})
|
||||
this.wsServer.listen(this.port, this.visibility)
|
||||
}catch(e){
|
||||
//@ts-ignore
|
||||
this.errorHandler(undefined)("Unable to connect to socket")
|
||||
}
|
||||
}
|
||||
|
||||
protected initRPCs(socket:Socket){
|
||||
const infoRPC:socketioRPC[] = [
|
||||
{
|
||||
name: 'info',
|
||||
type: 'call',
|
||||
func: async () => rpcInfos
|
||||
}
|
||||
]
|
||||
|
||||
const rpcInfos:ExtendedRpcInfo[] = [
|
||||
...rpcHooker(socket, "RPC", infoRPC, false),
|
||||
...this.rpcExporters.flatMap(exporter => rpcHooker(socket, exporter.name, [...exporter.exportPublicRPCs(), ...exporter.exportRPCs()]))
|
||||
]
|
||||
}
|
||||
|
||||
protected initPublicRPCs(socket:Socket){
|
||||
const adminRPCs:socketioRPC[] = [
|
||||
{
|
||||
name: 'info',
|
||||
type: 'call',
|
||||
func: async () => rpcInfos
|
||||
}
|
||||
]
|
||||
|
||||
const rpcInfos:ExtendedRpcInfo[] = [
|
||||
...rpcHooker(socket, "Admin", adminRPCs, false),
|
||||
...this.rpcExporters.flatMap(exporter => rpcHooker(socket, exporter.name, exporter.exportPublicRPCs()))
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import { SocketioRPC, Name } from "../Types";
|
||||
|
||||
export interface Exporter{
|
||||
name: Name
|
||||
exportRPCs() : SocketioRPC[]
|
||||
exportPublicRPCs() : SocketioRPC[]
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { OnFunction } from "../Types";
|
||||
|
||||
export interface Socket {
|
||||
port: number
|
||||
hook: (rpcname: string, ...args: any[]) => Socket
|
||||
unhook: (rpcname:string) => Socket
|
||||
call: (rpcname:string, ...args: any[]) => Promise<any>
|
||||
fire: (rpcname:string, ...args: any[]) => Promise<any>
|
||||
on: OnFunction
|
||||
destroy: ()=>void
|
||||
close: ()=>void
|
||||
}
|
||||
@@ -4,10 +4,10 @@ const TerserPlugin = require('terser-webpack-plugin');
|
||||
module.exports = {
|
||||
mode: 'production',
|
||||
target: "web",
|
||||
entry: path.resolve(__dirname, 'RPCSocket.ts'),
|
||||
entry: path.resolve(__dirname, 'Client.ts'),
|
||||
output: {
|
||||
path: path.resolve(__dirname, '../../lib'),
|
||||
filename: 'RPCaller.min.js',
|
||||
filename: 'Frontend.min.js',
|
||||
libraryTarget: 'commonjs',
|
||||
},
|
||||
resolve: {
|
||||
+4
-4
@@ -1,8 +1,8 @@
|
||||
import { RPCSocketServer } from '../src/backend/RPCSocketServer'
|
||||
import { Server } from '../src/Server'
|
||||
//@ts-ignore
|
||||
import {RPCSocket} from '../src/frontend/RPCSocket'
|
||||
import {Client} from '../src/Client'
|
||||
|
||||
new RPCSocketServer(20000, [{
|
||||
new Server(20000, [{
|
||||
name: "HelloWorldRPCGroup",
|
||||
exportPublicRPCs: () => [],
|
||||
exportRPCs: () => [{
|
||||
@@ -12,7 +12,7 @@ new RPCSocketServer(20000, [{
|
||||
}],
|
||||
}])
|
||||
|
||||
const caller = new RPCSocket(20000, 'localhost')
|
||||
const caller = new Client(20000, 'localhost')
|
||||
caller.connect().then(_ => {
|
||||
caller.info().then(console.log)
|
||||
caller["HelloWorldRPCGroup"].echo("x").then(console.log)
|
||||
|
||||
Reference in New Issue
Block a user