octopus-rpc
v2.8.0
Published
Super easy namespaced & bi-directional RPC over multiple transport types.
Downloads
7
Readme
Octopus RPC
Super easy bi-directional RPCs, for Node JS & the browser, that just work !
- Handles an arbitrary mix of transports, including socket.io, Node forked (child) processes, websockets.
- Pluggable architecture, so you can easily add your own custom transports.
- RPC Calls are namespaced debug style ! ( ie local:child:* )
- Namespaces can be set dynamically from either end of the connection (calling or providing), at any time.
In use @ :
Install
Use below commmand for Node. Browserify can be used to bundle for the browser.
npm install octopus-rpc --save
Demo
See demo folder for an example - simple microservice style usage with node child process.
- Clone the repo
- Run demo/index.js using Node
Usage
1. Create a new RPC endpoint on each participating node
Each node should add itself under a unique namespace. The namespaces are dynamic, and can be changed from either side of the rpc (ie, calling or providing )
const octopus = require('octopus-rpc');
var rpc = octopus('local:parent:parent1');
2. Add RPC commands & providers.
Providers are optional. They are automatically set up across all transports, previously added to the RPC instance.
const octopus = require('octopus-rpc');
var rpc = octopus('local:parent:parent1');
var hello = rpc.command('hello');
hello.provide((data, prev, transportName)=> {
// some action here
});
3. Add transports & call RPCs with 'debug' like namespace filters !
Transports are a standard, direct connection (socket), between 2 participating entities. (for eg: client to server socket). Currently supported transports are socket.io, node forked (child) processes, websockets. Octopus expects a ready socket connection and does not handle connection/reconnections. That is left to the user to implement.
const octopus = require('octopus-rpc');
var rpc = octopus('local:parent:parent1');
var hello = rpc.command('hello');
hello.provide((data, prev, transportName)=> {
// some action here
});
const { fork } = require('child_process');
const child1 = fork('child1.js');
const child2 = fork('child2.js');
var tasks = [];
tasks.push(rpc.over(child1, 'processRemote'));
tasks.push(rpc.over(child2, 'processRemote'));
Promise.all(tasks)
.then(()=>{
hello.call('local:*', 'aloha')
.then((res)=>console.log(res));
});
Transport type | String identifier --- | --- child process | 'processRemote' Socket.io | 'socketio' Websocket | 'websocket'
Full example
Copied from the demo folder
index.js
const { fork } = require('child_process');
const octopus = require('octopus-rpc');
const child1 = fork('child1.js');
const child2 = fork('child2.js');
var rpc = octopus('local:parent:parent1');
var hello = rpc.command('hello');
hello.provide(function (data, prev, transportName) {
return 'Parent :- Hey there ! ' + data.from;
});
var tasks = [];
tasks.push(rpc.over(child1, 'processRemote'));
tasks.push(rpc.over(child2, 'processRemote'));
Promise.all(tasks)
.then(()=>{
// Data passed to a call can be a value, or a function. If function, it is evaluated for every transport that matches the filter, and the return value of the function is used as data.
hello.call('local:child:child1',{from:'Parent'})
.then((resp) => console.log('\n\nGot "hello local:child:child1" response as :\n',resp));
hello.call('local:child:child2',{from:'Parent'})
.then((resp) => console.log('\n\nGot "hello local:child:child2" response as :\n',resp));
hello.call('local:child:*',{from:'Parent'})
.then((resp) => console.log('\n\nGot "hello local:child:*" response as :\n',resp));
});
child1.js
const octopus = require('octopus-rpc');
var rpc = octopus('local:child:child1');
rpc.over(process, 'processRemote');
var hello = rpc.command('hello');
hello.provide(function (data, prev, transportName) {
return 'child1 :- Hey there ! ' + data.from;
});
child2.js
const octopus = require('octopus-rpc');
var rpc = octopus('local:child:child2');
rpc.over(process, 'processRemote');
var hello = rpc.command('hello');
hello.provide(function (data, prev, transportName) {
return 'child2 :- Hey there ! ' + data.from;
});