Giter Site home page Giter Site logo

muxrpc's Introduction

muxrpc

combined rpc and multiplexing, with pull-streams.

build status

example

var MRPC = require('muxrpc')
var pull = require('pull-stream')

//we need a manifest of methods we wish to expose.
var api = {
  //async is a normal async function
  hello: 'async',

  //source is a pull-stream (readable)
  stuff: 'source'

  //TODO: sink and duplex pull-streams
}

//pass the api into the constructor, and then pass the object you are wrapping
//(if there is a local api)
var client = MRPC(api, null) () //remoteApi, localApi
var server = MRPC(null, api) ({
  hello: function (name, cb) {
    cb(null, 'hello, ' + name + '!')
  },
  stuff: function () {
    return pull.values([1, 2, 3, 4, 5])
  }
})

// pass in a cb for the stream end event
var a = client.createStream(console.log.bind(console, 'stream is closed'))
var b = server.createStream()
// or subscribe to the 'closed' event
b.once('closed', console.log.bind(console, 'stream is closed'))

pull(a, b, a) //pipe together

client.hello('world', function (err, value) {
  if(err) throw err
  console.log(value)
  // hello, world!
})

pull(client.stuff(), pull.drain(console.log))
// 1
// 2
// 3
// 4
// 5

Manifest

like multilevel, a manifest is required except it works a little differently, and since muxrpc works with any api, not assuming leveldb then you must write the manifest yourself.

The manifest is simply an object mapping to strings, or nested objects.

{
  foo: 'async',        //a function with a callback.
  bar: 'sync',         //a function that returns a value
                       //(note this is converted to an async function for the client)
  allTheFoos: 'source' //a source pull-stream (aka, readable)
  writeFoos: 'sink',   //a sink pull-stream (aka, writable)
  fooPhone: 'duplex',  //a duplex pull-stream

  //create nested objects like this:
  bar: {
    ...
  }
}

Permissions

If you are exposing an api over a network connection, then you probably want some sort of authorization system. muxrpc@4 and earlier had a rpc.permissions() method on the rpc object, but this has been removed. Now you must pass a permissions function, which is called with the name (a path) and args, if this function does not throw an error, then the call is allowed.

In some cases, a simple allow/deny list is sufficient. A helper function, is provided, which was a part of muxrpc@4

var Permissions = require('muxrpc/permissions')

var api = {
  foo: 'async',
  bar: 'async',
  auth: 'async'
}

//set initial settings
var perms = Perms({allow: ['auth']})

var rpc = muxrpc(null, api, serializer)({
  foo: function (val, cb) {
    cb(null, {okay: 'foo'})
  },
  bar: function (val, cb) {
    cb(null, {okay: 'bar'})
  },
  auth: function (pass, cb) {
    //implement an auth function that sets the permissions,
    //using allow or deny lists.

    if(pass === 'whatever')
      perms({deny: ['bar']}) //allow everything except "bar"
    else if(pass === 's3cr3tz')
      perms({}) //allow everything!!!
    else return cb(new Error('ACCESS DENIED'))

    //else we ARE authorized.
    cb(null, 'ACCESS GRANTED')
  }
}, perms)

//Get a stream to connect to the remote. As in the above example!
var ss = rpc.createStream()

bootstrapping

sometimes you don't know the remote manifest yet. if you pass a callback instead of remoteApi a an async method manifest is called on the remote which should return a manifest. This then used as the remote manifest and the callback is called.

var manifest = { hello: 'sync', manifest: 'sync' }

var bob = Muxrpc(null, manifest)  ({
  hello: function (n) {
    if(this._emit) this._emit('hello', n)
    console.log('hello from ' + this.id)
    return n + ':' + this.id
  },
  manifest: function () {
    return manifest
  }
})

var alice = Muxrpc(function (err, alice) {
  //alice now knows the bob's api
})
var as = alice.createStream()
pull(as, bob.createStream(), as)

License

MIT

muxrpc's People

Contributors

dominictarr avatar pfrazee avatar mlegore avatar christianbundy avatar nichoth avatar reqshark avatar

Watchers

James Cloos avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.