This repository has been archived on 2023-04-09. You can view files and clone it, but cannot push or open issues or pull requests.
kernel-protomux/README.md

180 lines
3.9 KiB
Markdown
Raw Permalink Normal View History

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 protocol channels
2021-12-30 20:13:47 +00:00
const cool = mux.createChannel({
2022-03-11 01:10:04 +00:00
protocol: 'cool-protocol',
id: Buffer.from('optional binary id'),
onopen () {
2021-12-30 20:13:47 +00:00
console.log('the other side opened this protocol!')
},
2022-03-11 01:10:04 +00:00
onclose () {
console.log('either side closed the protocol')
2021-12-30 20:13:47 +00:00
}
})
2022-02-01 18:09:56 +00:00
// And add some messages
const one = cool.addMessage({
encoding: c.string,
onmessage (m) {
console.log('recv message (1)', m)
}
})
const two = cool.addMessage({
encoding: c.bool,
onmessage (m) {
console.log('recv message (2)', m)
}
})
2022-11-03 09:39:15 +00:00
// open the channel
2022-11-03 09:39:15 +00:00
cool.open()
2022-02-01 18:09:56 +00:00
// 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.
2022-03-11 01:10:04 +00:00
alloc (size) {}
2021-12-30 20:13:47 +00:00
}
```
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).
#### `const channel = mux.createChannel(opts)`
2021-12-30 20:13:47 +00:00
Add a new protocol channel.
2021-12-30 20:13:47 +00:00
Options include:
``` js
{
// Used to match the protocol
2022-03-11 01:10:04 +00:00
protocol: 'name of the protocol',
// Optional additional binary id to identify this channel
2022-03-11 01:10:04 +00:00
id: buffer,
// Optional encoding for a handshake
handshake: encoding,
2022-03-11 01:10:04 +00:00
// Optional array of messages types you want to send/receive.
messages: [],
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 onopen (handshake) {},
// Called when the channel closes - ie the remote side closes or rejects this protocol or we closed it.
2021-12-30 20:13:47 +00:00
// Errors here are caught and forwared to stream.destroy
2022-03-11 01:10:04 +00:00
async onclose () {},
// Called after onclose when all pending promises has resolved.
async ondestroy () {}
2021-12-30 20:13:47 +00:00
}
2021-11-10 14:15:09 +00:00
```
Sessions are paired based on a queue, so the first remote channel with the same `protocol` and `id`.
2022-03-11 01:10:04 +00:00
__NOTE__: `mux.createChannel` returns `null` if the channel should not be opened, ie it's a duplicate channel or the remote has already closed this one.
2022-03-11 01:10:04 +00:00
If you want multiple sessions with the same `protocol` and `id`, set `unique: false` as an option.
2021-12-30 20:13:47 +00:00
#### `const opened = mux.opened({ protocol, id })`
Boolean that indicates if the channel is opened.
#### `mux.pair({ protocol, id }, callback)`
Register a callback to be called everytime a new channel is requested.
#### `mux.unpair({ protocol, id })`
Unregisters the pair callback.
#### `channel.open([handshake])`
Open the channel.
#### `const m = channel.addMessage(opts)`
2021-12-30 20:13:47 +00:00
Add/register a message type for a certain encoding. Options include:
2021-12-30 20:13:47 +00:00
2022-02-01 18:09:56 +00:00
``` js
{
// 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.
#### `channel.close()`
2021-12-30 20:13:47 +00:00
Closes the protocol channel.
2021-12-30 20:13:47 +00:00
#### `channel.cork()`
2021-12-30 20:13:47 +00:00
Corking the protocol channel, makes it buffer messages and send them all in a batch when it uncorks.
2021-12-30 20:13:47 +00:00
#### `channel.uncork()`
2021-12-30 20:13:47 +00:00
Uncork and send the batch.
#### `mux.cork()`
Same as `channel.cork` but on the muxer instance.
2021-12-30 20:13:47 +00:00
#### `mux.uncork()`
Same as `channel.uncork` but on the muxer instance.
2021-12-30 20:13:47 +00:00
#### `for (const channel of muxer) { ... }`
The muxer instance is iterable, so you can iterate over all the channels.
2021-11-10 14:15:09 +00:00
## License
MIT