123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- import { RPCServer, RPCSocket } from './Index'
- import { RPCExporter } from './src/Interfaces'
- import { RPCInterface } from './src/Types'
-
- // TL;DR
- const echo = (text: string) => text
- const add = (a: number, b: number) : number => a + b
- const getAsync = async () : Promise<{topic: string, message:string}>=> await new Promise((res, _) => {
- setTimeout(() => {
- res({
- topic: "Hey!!",
- message: "Hello World Async!"
- })
- }, 250)
- })
- const getCallback = (callback: Function) : string => {
- setTimeout(() => {
- try{
- callback({
- topic: "Hey!!",
- message: "Hello World Callback!"
- })
- }catch(e){
- console.log(String(e))
- }
- }, 250)
- return "Please wait for a callback :)"
- }
- new RPCServer(20000, [{
- name: 'MyRPCGroup1',
- exportRPCs: () => [
- echo,
- add,
- getAsync,
- {
- name: 'getCallback',
- hook: getCallback,
- onClose: (response, rpc) => { /* ... */ },
- onCallback: (...callbackArgs) => { /* ... */ }
- }
- ]
- }])
-
- new RPCSocket(20000, 'localhost').connect().then(async sock => {
- try{
- const RPCs = sock['MyRPCGroup1']
- await RPCs.echo("hello!").then(console.log)
- await RPCs.add(1, Math.PI).then(console.log)
- await RPCs.getAsync().then(console.log)
- await RPCs.getCallback(console.log).then(console.log)
- }catch(e){
- console.log(String(e))
- }
- })
-
- //Hooks and events
- new RPCServer(20001, [{
- name: 'MyRPCGroup1',
- exportRPCs: () => [
- echo,
- add,
- getAsync,
- {
- name: 'getCallback',
- hook: getCallback,
- onClose: (response, rpc) => { /* client disconnected */ },
- onCallback: (...callbackArgs) => { /* callback triggered */ }
- }
- ],
- }], {
- visibility: '127.0.0.1', //0.0.0.0
- closeHandler: (socket) => { /* global close handler */ },
- connectionHandler: (socket) => { /* new connection made */ },
- errorHandler: (socket, error, rpcname, argArr) => { /* An error occured inside a RPC */ },
- })
-
- const sock = new RPCSocket(20001, 'localhost')
- sock.on('error', (e) => { /* handle error */ })
- sock.on('close', () => { /* handle close event */ })
-
- sock.hook('RPCName', (/* arg0, arg1, ..., argN */) => { /* bind client-side RPCs */ })
- //Retrieve the socket from connectionHandler (Server-side) and trigger with
- //socket.call('RPCName', arg0, arg1, ..., argN)
-
- sock.connect().then(_ => { /* ... */})
-
- //Restricting access
- new RPCServer(20002, [{
- name: 'MyRPCGroup1',
- exportRPCs: () => [
- echo,
- add,
- getAsync,
- {
- name: 'getCallback',
- hook: getCallback,
- }
- ],
- }], {
- sesame: "sesame open",
- /*
- OR check sesame dynamically
- and refine permissioning with accessfilter (optional)
- */
-
- //sesame: (sesame) => true
- //accessFilter: (sesame, exporter) => { return exporter.name === "MyRPCGroup1" && sesame === "sesame open" },
- })
-
- new RPCSocket(20002, 'localhost').connect("sesame open").then(async sock => {
- try{
- const RPCs = sock['MyRPCGroup1']
- await RPCs.echo("hello!").then(console.log)
- await RPCs.add(1, Math.PI).then(console.log)
- await RPCs.getAsync().then(console.log)
- await RPCs.getCallback(console.log).then(console.log)
- }catch(e){
- console.log(String(e))
- }
- })
-
-
- //TypeScript and pseudo-interfaces
-
- type MyInterface = {
- MyRPCGroup1: {
- echo: (x: string) => string
- add: (a: number, b: number) => number
- getAsync: () => Promise<{ topic: string, message: string }>
- getCallback: (callback:Function) => string
- }
- };
-
-
- /*
- exportRPCs is now type safe. Try swapping echo for badEcho.
- Sadly TSC's stack traces aren't the best, but try to scroll to the bottom of them to find useful info like
-
- Type '(x: boolean) => number' is not assignable to type '(x: string) => string'
- */
-
- const badEcho = (x: boolean) : number => 3
-
- new RPCServer<MyInterface>(20003, [{
- name: 'MyRPCGroup1',
- exportRPCs: () => [
- //badEcho,
- echo,
- add,
- getAsync,
- {
- name: 'getCallback',
- hook: getCallback,
- }
- ],
- }])
-
- new RPCSocket<MyInterface>(20003, 'localhost').connect().then(async sock => {
- try{
- await sock.MyRPCGroup1.echo("hello!").then(console.log)
- await sock.MyRPCGroup1.add(1, Math.PI).then(console.log)
- await sock.MyRPCGroup1.getAsync().then(console.log)
- await sock.MyRPCGroup1.getCallback(console.log).then(console.log)
- }catch(e){
- console.log(String(e))
- }
- })
-
-
- //Class-based pattern
-
- interface IMyImplementation {
- echo: (x: string) => string
- add: (a: number, b: number) => number
- getAsync: () => Promise<{ topic: string, message: string }>
- getCallback: (callback:Function) => string
- }
-
- type IfcGenerator<Name extends string, Interface, keys extends keyof Interface = keyof Interface> = {
- [name in Name]: {
- [key in keys] : Interface[key]
- }
- }
-
- type MyIfc = IfcGenerator<"MyRPCGroup1", IMyImplementation>
-
- class MyImplementation implements IMyImplementation, RPCExporter<MyIfc>{
- //"X" as "X" syntax is required to satisfy the type system (as it assumes string)
- name = "MyRpcGroup11" as "MyRPCGroup1"
-
- //List the functions you declared in MyIfc
- exportRPCs = () => [
- this.echo,
- this.add,
- this.getAsync,
- this.getCallback
- ]
-
- //Write your implementations as you normally would
- echo = (text: string) => text
-
- add = (a: number, b: number) : number => a + b
-
- getAsync = async () : Promise<{topic: string, message:string}>=> await new Promise((res, _) => {
- setTimeout(() => {
- res({
- topic: "Hey!!",
- message: "Hello World Async!"
- })
- }, 250)
- })
-
- getCallback = (callback: Function) : string => {
- setTimeout(() => {
- try{
- callback({
- topic: "Hey!!",
- message: "Hello World Callback!"
- })
- }catch(e){
- console.log(String(e))
- }
- }, 250)
- return "Please wait for a callback :)"
- }
- }
-
- new RPCServer<MyIfc>(20004, [new MyImplementation(), /* ... other RPCExporters */])
-
- new RPCSocket<MyIfc>(20004, 'localhost').connect().then(async sock => {
- try{
- await sock.MyRPCGroup1.echo("hello!").then(console.log)
- await sock.MyRPCGroup1.add(1, Math.PI).then(console.log)
- await sock.MyRPCGroup1.getAsync().then(console.log)
- await sock.MyRPCGroup1.getCallback(console.log).then(console.log)
- }catch(e){
- console.log(String(e))
- }
- })
|