UNPKG

4.11 kBMarkdownView Raw
1# muxrpc
2
3combined rpc and multiplexing, with pull-streams.
4
5[![build status](https://secure.travis-ci.org/ssbc/muxrpc.png)](http://travis-ci.org/ssbc/muxrpc)
6
7
8## example
9
10``` js
11
12var MRPC = require('muxrpc')
13var pull = require('pull-stream')
14
15//we need a manifest of methods we wish to expose.
16var api = {
17 //async is a normal async function
18 hello: 'async',
19
20 //source is a pull-stream (readable)
21 stuff: 'source'
22
23 //TODO: sink and duplex pull-streams
24}
25
26//pass the api into the constructor, and then pass the object you are wrapping
27//(if there is a local api)
28var client = MRPC(api, null) () //remoteApi, localApi
29var server = MRPC(null, api) ({
30 hello: function (name, cb) {
31 cb(null, 'hello, ' + name + '!')
32 },
33 stuff: function () {
34 return pull.values([1, 2, 3, 4, 5])
35 }
36})
37
38// pass in a cb for the stream end event
39var a = client.createStream(console.log.bind(console, 'stream is closed'))
40var b = server.createStream()
41// or subscribe to the 'closed' event
42b.once('closed', console.log.bind(console, 'stream is closed'))
43
44pull(a, b, a) //pipe together
45
46client.hello('world', function (err, value) {
47 if(err) throw err
48 console.log(value)
49 // hello, world!
50})
51
52pull(client.stuff(), pull.drain(console.log))
53// 1
54// 2
55// 3
56// 4
57// 5
58```
59
60## Manifest
61
62like multilevel, a [manifest is required](https://github.com/juliangruber/multilevel#plugins)
63except it works a little differently, and since muxrpc works with any api,
64not assuming leveldb then you must write the manifest yourself.
65
66The manifest is simply an object mapping to strings, or nested objects.
67
68``` js
69{
70 foo: 'async', //a function with a callback.
71 bar: 'sync', //a function that returns a value
72 //(note this is converted to an async function for the client)
73 allTheFoos: 'source' //a source pull-stream (aka, readable)
74 writeFoos: 'sink', //a sink pull-stream (aka, writable)
75 fooPhone: 'duplex', //a duplex pull-stream
76
77 //create nested objects like this:
78 bar: {
79 ...
80 }
81}
82
83```
84
85## Permissions
86
87If you are exposing an api over a network connection,
88then you probably want some sort of authorization system.
89`muxrpc@4` and earlier had a `rpc.permissions()` method on
90the rpc object, but this has been removed.
91Now you must pass a permissions function, which is called with
92the `name` (a path) and `args`, if this function does not throw
93an error, then the call is allowed.
94
95In some cases, a simple allow/deny list is sufficient.
96A helper function, is provided, which was a part of muxrpc@4
97
98``` js
99
100var Permissions = require('muxrpc/permissions')
101
102var api = {
103 foo: 'async',
104 bar: 'async',
105 auth: 'async'
106}
107
108//set initial settings
109var perms = Perms({allow: ['auth']})
110
111var rpc = muxrpc(null, api, serializer)({
112 foo: function (val, cb) {
113 cb(null, {okay: 'foo'})
114 },
115 bar: function (val, cb) {
116 cb(null, {okay: 'bar'})
117 },
118 auth: function (pass) {
119 //implement an auth function that sets the permissions,
120 //using allow or deny lists.
121
122 if(pass === 'whatever')
123 perms({deny: ['bar']}) //allow everything except "bar"
124 else if(pass === 's3cr3tz')
125 perms({}) //allow everything!!!
126 else return cb(new Error('ACCESS DENIED'))
127
128 //else we ARE authorized.
129 cb(null, 'ACCESS GRANTED')
130 }
131}, perms)
132
133//Get a stream to connect to the remote. As in the above example!
134var ss = rpc.createStream()
135
136```
137
138## bootstrapping
139
140sometimes you don't know the remote manifest yet. if you pass a callback
141instead of `remoteApi` a an async method `manifest` is called on the remote
142which should return a manifest. This then used as the remote manifest
143and the callback is called.
144
145``` js
146
147var manifest = { hello: 'sync', manifest: 'sync' }
148
149var bob = Muxrpc(null, manifest) ({
150 hello: function (n) {
151 if(this._emit) this._emit('hello', n)
152 console.log('hello from ' + this.id)
153 return n + ':' + this.id
154 },
155 manifest: function () {
156 return manifest
157 }
158})
159
160var alice = Muxrpc(function (err, alice) {
161 //alice now knows the bob's api
162})
163var as = alice.createStream()
164pull(as, bob.createStream(), as)
165```
166
167## License
168
169MIT
170
171
172
173
174