2021-11-10 14:15:09 +00:00
|
|
|
# protomux
|
|
|
|
|
|
|
|
Multiplex multiple message oriented protocols over a stream
|
|
|
|
|
|
|
|
```
|
|
|
|
npm install protomux
|
|
|
|
```
|
|
|
|
|
|
|
|
## Usage
|
|
|
|
|
|
|
|
``` js
|
|
|
|
const Protomux = require('protomux')
|
2021-12-30 20:13:47 +00:00
|
|
|
const c = require('compact-encoding')
|
|
|
|
|
|
|
|
// By framed stream, it has be a stream that preserves the messages, ie something that length prefixes
|
|
|
|
// like @hyperswarm/secret-stream
|
|
|
|
|
|
|
|
const mux = new Protomux(aStreamThatFrames)
|
|
|
|
|
|
|
|
// Now add some protocols
|
|
|
|
|
|
|
|
const cool = mux.addProtocol({
|
|
|
|
name: 'cool-protocol',
|
|
|
|
version: {
|
|
|
|
major: 1,
|
|
|
|
minor: 0
|
|
|
|
},
|
2022-02-01 18:09:56 +00:00
|
|
|
messages: 2, // protocol has 2 messages
|
2021-12-30 20:13:47 +00:00
|
|
|
onremoteopen () {
|
|
|
|
console.log('the other side opened this protocol!')
|
|
|
|
},
|
2022-02-01 18:09:56 +00:00
|
|
|
onremoteclose () {
|
2021-12-30 20:13:47 +00:00
|
|
|
console.log('the other side closed this protocol!')
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2022-02-01 18:09:56 +00:00
|
|
|
// And add some messages
|
|
|
|
|
|
|
|
const one = cool.addMessage({
|
|
|
|
type: 0,
|
|
|
|
encoding: c.string,
|
|
|
|
onmessage (m) {
|
|
|
|
console.log('recv message (1)', m)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
const two = cool.addMessage({
|
|
|
|
type: 1,
|
|
|
|
encoding: c.bool,
|
|
|
|
onmessage (m) {
|
|
|
|
console.log('recv message (2)', m)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
// And send some data
|
2021-12-30 20:13:47 +00:00
|
|
|
|
2022-02-01 18:09:56 +00:00
|
|
|
one.send('a string')
|
|
|
|
two.send(true)
|
2021-12-30 20:13:47 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
## API
|
|
|
|
|
|
|
|
#### `mux = new Protomux(stream, [options])`
|
|
|
|
|
|
|
|
Make a new instance. `stream` should be a framed stream, preserving the messages written.
|
|
|
|
|
|
|
|
Options include:
|
|
|
|
|
|
|
|
``` js
|
|
|
|
{
|
|
|
|
// Called when the muxer wants to allocate a message that is written, defaults to Buffer.allocUnsafe.
|
|
|
|
alloc (size) {},
|
|
|
|
// Hook that is called when an unknown protocol is received. Should return true/false.
|
|
|
|
async onacceptprotocol ({ name, version }) {}
|
|
|
|
// How many protocols can be remote open, that we haven't opened yet?
|
|
|
|
// Only used if you don't provide an accept hook.
|
|
|
|
backlog: 128
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2022-01-28 15:00:09 +00:00
|
|
|
#### `mux = Protomux.from(stream | muxer, [options])`
|
|
|
|
|
|
|
|
Helper to accept either an existing muxer instance or a stream (which creates a new one).
|
|
|
|
|
2021-12-30 20:13:47 +00:00
|
|
|
#### `const p = mux.addProtocol(opts)`
|
|
|
|
|
|
|
|
Add a new protocol.
|
|
|
|
|
|
|
|
Options include:
|
|
|
|
|
|
|
|
``` js
|
|
|
|
{
|
|
|
|
// Used to match the protocol
|
|
|
|
name: 'name of the protocol',
|
|
|
|
// You can have multiple versions of the same protocol on the same stream.
|
|
|
|
// Protocols are matched using the major version only.
|
|
|
|
version: {
|
|
|
|
major: 0,
|
|
|
|
minor: 0
|
|
|
|
},
|
2022-02-01 18:09:56 +00:00
|
|
|
// Number of messages types you want to send/receive.
|
|
|
|
messages: 2,
|
2021-12-30 20:13:47 +00:00
|
|
|
// Called when the remote side adds this protocol.
|
|
|
|
// Errors here are caught and forwared to stream.destroy
|
|
|
|
async onremoteopen () {},
|
|
|
|
// Called when the remote side closes or rejects this protocol.
|
|
|
|
// Errors here are caught and forwared to stream.destroy
|
2022-02-01 18:09:56 +00:00
|
|
|
async onremoteclose () {}
|
2021-12-30 20:13:47 +00:00
|
|
|
}
|
2021-11-10 14:15:09 +00:00
|
|
|
```
|
|
|
|
|
2021-12-30 20:13:47 +00:00
|
|
|
Each of the functions can also be set directly on the instance with the same name.
|
|
|
|
|
2022-02-01 18:09:56 +00:00
|
|
|
#### `const m = p.addMessage(opts)`
|
2021-12-30 20:13:47 +00:00
|
|
|
|
2022-02-01 18:09:56 +00:00
|
|
|
Specify a message. Options include:
|
2021-12-30 20:13:47 +00:00
|
|
|
|
2022-02-01 18:09:56 +00:00
|
|
|
``` js
|
|
|
|
{
|
|
|
|
// Defaults to an incrementing number
|
|
|
|
type: numericIndex,
|
|
|
|
// compact-encoding specifying how to encode/decode this message
|
|
|
|
encoding: c.binary,
|
|
|
|
// Called when the remote side sends a message.
|
|
|
|
// Errors here are caught and forwared to stream.destroy
|
|
|
|
async onmessage (message) { }
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
#### `m.send(data)`
|
|
|
|
|
|
|
|
Send a message.
|
|
|
|
|
|
|
|
#### `m.onmessage`
|
|
|
|
|
|
|
|
Function that is called when a message arrives.
|
|
|
|
|
|
|
|
#### `m.encoding`
|
|
|
|
|
|
|
|
The encoding for this message.
|
|
|
|
|
|
|
|
#### `p.close()`
|
2021-12-30 20:13:47 +00:00
|
|
|
|
2022-02-01 18:09:56 +00:00
|
|
|
Closes the protocol.
|
2021-12-30 20:13:47 +00:00
|
|
|
|
|
|
|
#### `p.cork()`
|
|
|
|
|
|
|
|
Corking the protocol, makes it buffer messages and send them all in a batch when it uncorks.
|
|
|
|
|
|
|
|
#### `p.uncork()`
|
|
|
|
|
|
|
|
Uncork and send the batch.
|
|
|
|
|
|
|
|
#### `mux.cork()`
|
|
|
|
|
|
|
|
Same as `p.cork` but on the muxer instance.
|
|
|
|
|
|
|
|
#### `mux.uncork()`
|
|
|
|
|
|
|
|
Same as `p.uncork` but on the muxer instance.
|
|
|
|
|
2021-11-10 14:15:09 +00:00
|
|
|
## License
|
|
|
|
|
|
|
|
MIT
|