Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
peter 42c2d4d3ec npm ver bump il y a 4 ans
src sesamefilter il y a 4 ans
test sesamefilter il y a 4 ans
.drone.yml retry il y a 5 ans
.gitignore automate documentation il y a 5 ans
Index.ts moved RPCLibrary to Index il y a 5 ans
LICENSE.md added mit license il y a 5 ans
README.md cleanup metadata il y a 5 ans
package-lock.json tempalte strings & bugfixes il y a 4 ans
package.json npm ver bump il y a 4 ans
tsconfig.json werks il y a 5 ans

README.md

Overview

Build Status Current Version Weekly Downloads License Type

rpclibrary is a websocket on steroids!

How to install

npm i rpclibrary

Quickstart

import {RPCServer, RPCSocket} from 'rpclibrary' 

const port = 1234
const host = 'locahost'

const echo = (x) => x

const server = new RPCServer(port, [{
    name: 'HelloWorldRPCGroup',
    exportRPCs: ()  => [
        echo, //named function variable
        function echof(x){ return x }, //named function
        {
            name: 'echoExplicit', //describing object
            call: async (x) => x
        }
    ]
}])

const client = new RPCSocket(port, host)

client.connect().then(async () => {
    const r0 = await client['HelloWorldRPCGroup'].echo('Hello')
    const r1 = await client['HelloWorldRPCGroup'].echof('World')
    const r2 = await client['HelloWorldRPCGroup'].echoExplicit('RPC!')

    console.log(r0,r1,r2) //Hello World RPC!
})

Using callbacks

rpclibrary offers a special type of call that can be used with callbacks. The callback has to be the last argument and may be the only passed function.

In order to function, some metadata has to be included in the return value of hooks. On success, the function is expected to return a { result: 'Success', uuid: string } (Types.SubscriptionResponse) or in case of errors a { result: 'Error' }(Types.ErrorResponse).

The uuid, as the name implies, is used to uniquely identify the callback for a given invocation and also dictates the name given to the client-side RPC. Unless you got a preferred way of generating these (e.g. using some kind of unique information important to your task) we recommend uuid for this purpose.

You should unhook the client socket once you’re done with it as not to cause security or control flow issues.

import {RPCServer, RPCSocket} from 'rpclibrary'

const port = 1234
const host = 'locahost'

const callbacks:Map<string, Function> = new Map()

new RPCServer(port, [{
    name: 'HelloWorldRPCGroup',
    exportRPCs: ()  => [
        function  triggerCallbacks(...messages){ callbacks.forEach(cb => cb.apply({}, messages)) },
        {
            name: 'subscribe',
            hook: async (callback) => {
                const randStr = 'generate_a_random_string_here'
                callbacks.set(randStr, callback); 
                return { result: 'Success', uuid: randStr} 
            }
        },{
            name: 'unsubscribe',
            call: async (uuid) => { callbacks.delete(uuid) }
        }
    ]
}])

const client = new RPCSocket(port, host)
client.connect().then(async () => {
    const res = await client['HelloWorldRPCGroup'].subscribe(async (...args:any) => {
        console.log.apply(console, args)

        /* close the callbacks once you're done */
        await client['HelloWorldRPCGroup'].unsubscribe(res.uuid)
        client.unhook(res.uuid)
    })

    await client['HelloWorldRPCGroup'].triggerCallbacks("Hello", "World", "Callbacks")
})

If you need to include further response data into your SubscriptionResponse you can extend it using the server’s first generic parameter SubResType

new RPCServer<{extension: string}>(port, [{
    name: 'MyRPCGroup',
    exportRPCs: ()  => [{
        name: 'subscribe',
        hook: async (callback) => {
            return {
                result: 'Success',
                uuid: 'very_random_string',
                extension: 'your_data_here' //tsc will demand this field
            }
        }
    }]}
])

Experimental typing support

It is possible to declare pseudo-interfaces for servers and clients by using server’s second generic parameter. This feature is currently still in development and considered unstable and untested. Use with caution.

type MyInterface = { 
    Group1: { 
        triggerCallbacks: (...args:any[]) => Promise<void>,
        subscribe: (param:string, callback:Function) => Promise<SubscriptionResponse<{a: string}>>,
        unsubscribe: (uuid:string) => Promise<void>
    },
    Group2: {
        echo: (x:string) => Promise<string>
    }
}

Create a client using

RPCSocket.makeSocket<MyInterface>(port, host).then((async (client) => {
    const r = await client.Group2.echo("hee") //tsc knows about available RPCs 
}))

/* OR */

const client = new RPCSocket(port, host)
client.connect<MyInterface>().then((async (client) => {
    const r = await client.Group2.echo("hee") //tsc knows about available RPCs 
})) 

Create a server using

new RPCServer<{a:string}, MyInterface>(port, 
    [{
        //...
    },{
        name: 'Group2', //Auto completion for names
        exportRPCs: () => [{
            name: 'echo', //this name too!
            call: async (x) => x+"llo World!" //the paramter and return types are known by tsc 
        }]
    }]
)

Full documentation