mhub
所属分类:Websocket编程
开发工具:TypeScript
文件大小:0KB
下载次数:0
上传日期:2023-01-05 17:34:36
上 传 者:
sh-1993
说明: 使用websockets的简单、灵活的消息中心
(Simple, flexible message hub using websockets)
文件列表:
.coveralls.yml (24, 2020-05-02)
.editorconfig (152, 2020-05-02)
.mocharc.json (33, 2020-05-02)
.npmignore (209, 2020-05-02)
.prettierrc (65, 2020-05-02)
.travis.yml (142, 2020-05-02)
.vscode/ (0, 2020-05-02)
.vscode/launch.json (813, 2020-05-02)
.vscode/settings.json (130, 2020-05-02)
LICENSE.txt (1105, 2020-05-02)
bin/ (0, 2020-05-02)
bin/mhub-client (56, 2020-05-02)
bin/mhub-ping (54, 2020-05-02)
bin/mhub-server (56, 2020-05-02)
package-lock.json (96337, 2020-05-02)
package.json (2481, 2020-05-02)
server.conf.example.json (615, 2020-05-02)
server.conf.json (344, 2020-05-02)
src/ (0, 2020-05-02)
src/authenticator.ts (1811, 2020-05-02)
src/baseclient.ts (15991, 2020-05-02)
src/browserclient.ts (3741, 2020-05-02)
src/configparser.ts (4540, 2020-05-02)
src/dict.ts (944, 2020-05-02)
src/example/ (0, 2020-05-02)
src/example/custom-server.ts (4797, 2020-05-02)
src/hub.ts (8541, 2020-05-02)
src/hubclient.ts (8974, 2020-05-02)
src/index.ts (956, 2020-05-02)
src/localclient.ts (2622, 2020-05-02)
src/log.ts (112, 2020-05-02)
src/logger.ts (1963, 2020-05-02)
src/match.ts (813, 2020-05-02)
src/message.ts (3000, 2020-05-02)
src/mhub-client.ts (8512, 2020-05-02)
src/mhub-ping.ts (5378, 2020-05-02)
src/mhub-server.ts (2170, 2020-05-02)
... ...
# MHub message server and client
## Introduction
[MHub](https://github.com/poelstra/mhub) is a simple, flexible message bus
using a JSON-based protocol.
It natively supports websockets, but also 'plain' TCP ports.
Because both the protocol and the messages use JSON, this makes it very
powerful, yet still simple enough to be directly implemented in e.g. a
microcontroller.
It can be used as a lightweight Javascript-only alternative to e.g. RabbitMQ or
MQTT.
This project provides:
* a message broker (`mhub-server`) for loosely coupling software components
* accompanying command-line tools (`mhub-client`) for interacting with the server and
* a library for communicating with the server using Javascript.
## Packages using MHub
* [MHub for Node-RED](https://github.com/poelstra/node-red-contrib-mhub): MHub publish/subscribe nodes for [Node-RED](https://nodered.org/)
* [MHub Relay](https://github.com/poelstra/mhub-relay): advanced message routing/transformation between MHub servers (see below)
* FIRST Lego League tournament software
* [Display System](https://github.com/FirstLegoLeague/displaySystem)
* [Scoring](https://github.com/FirstLegoLeague/fllscoring)
* Arduino library (not published yet, contact [me](https://github.com/poelstra) if interested)
It's successfully powering my home automation for a few years now.
## Concepts
### Messages
The purpose of an MHub server (`mhub-server`) is to pass messages between
connected clients.
A *message* consists of a *topic* and optionally *data* and/or *headers*.
The *topic* of a message typically represents e.g. a command or event, like
`clock:arm`, `twitter:add` or `/home/lights/kitchen`.
*Data* can be the countdown time, tweet to add, light value, etc.
It can be anything that's valid in JSON.
Headers are for more advanced uses of the system, e.g. to support sending
messages between multiple brokers, but also e.g. to mark certain messages
to be persistent (i.e. any future subscriber will also receive it, see
`HeaderStore` below).
### Publish / subscribe (pubsub)
MHub (like many other message busses) supports the concept of publishing
messages and subscribing to topics (aka 'pubsub').
For example, a client that subscribes to all messages with the topic pattern
`twitter:*`, will receive messages published by other clients with topics such
as `twitter:add` or `twitter:remove`.
Any client can both publish messages and subscribe to other messages.
(Note: messages sent by a client will also be received by that client if it
matches one of its subscriptions).
The topic format is free-form, and pattern matching is done by
[minimatch](https://www.npmjs.com/package/minimatch). So, depending on the
needs and preferences of your applicatino, topics can look like
`someThing`, `some:thing`, `some/thing`, `/some/thing/`, etc.
For example, in my home automation system I'm using topics like:
- `/home/lights/kitchen`, `/home/lights/table`, etc: dimmer values for lights
- `/home/scene`: string value with the name of a scene to switch to (e.g. "dinner", "off", etc)
- `/dev/rfhub/rx`, `/dev/rfhub/tx`: received RF events and RF commands to be
transmitted (for controlling lights)
### Nodes and bindings
An MHub server (`mhub-server`) instance contains one or more *nodes*, on which
messages can be published or retrieved.
In many cases, the `default` node will suffice, but to allow for more
flexibility on larger systems, it is possible to define additional nodes.
For example, this mechanism can be used to:
* route tweets to an 'unmoderated' node first, pass through some moderator
system, then send them through to a 'moderated' node (which then can have
bindings to other nodes that are interested in these tweets, e.g. display
nodes).
* route a subset of all messages from an mhub-server on the local network to an
mhub-server on the Internet, e.g. for consumption by a public website.
* route team scores to both a video overlay display and dedicated score displays
in other areas, but only route the show/hide commands of the scores view to
the video overlay, such that the dedicated displays keep displaying their
scores.
* create a firehose node that emits all 'non-confidential' messages for display
on a public screen somewhere (we're targetting tech-events, right?).
For such larger systems, it is a good idea to assign every application instance
in the system (video display controller, video display, pit area display
controller, pit area display, scores subsystem, etc.) its own node.
*Bindings* then make it possible to selectively route certain messages (based on
their topic) between different nodes. A binding (optionally based on a topic
*pattern*, like subscriptions), forwards all (matching) messages from
its source node to its destination node.
These bindings can either directly be specified in the mhub-server configuration
(for routing between nodes on the same server), or through an external program
such as [mhub-relay](https://github.com/poelstra/mhub-relay) (for routing
between nodes on the same, and/or different servers).
## Basic installation and usage
To install and run the server:
```sh
npm install -g mhub
mhub-server
```
You'll now have an MHub server listening on port 13900 for websocket connections,
and 13902 for 'raw' TCP connections.
Start an `mhub-client` in listen mode on the `default` node:
```sh
mhub-client -l
```
In another terminal, publish some messages:
```sh
mhub-client -t /some/topic
mhub-client -t /some/topic -d 42
mhub-client -t /some/topic -d '"a message"'
mhub-client -t /some/topic -d '{"some": "object"}'
mhub-client -t /some/topic -d 123 -h '{"keep": true}'
```
Note how the data and header parameters accepts any JSON input, so it must be properly
quoted on the shell.
You'll see them turn up in the first terminal as:
```sh
Message { topic: '/some/topic', data: undefined, headers: {} }
Message { topic: '/some/topic', data: 42, headers: {} }
Message { topic: '/some/topic', data: 'a message', headers: {} }
Message { topic: '/some/topic', data: { some: 'object' }, headers: {} }
Message {
topic: '/some/topic',
data: { persistent: 'message' },
headers: { keep: true } }
Message { topic: '/some/topic', data: 123, headers: { keep: true } }
```
If you restart the listening MHub client (`mhub-client -l`), you'll now
immediately get:
```
Message { topic: '/some/topic', data: 123, headers: { keep: true } }
```
Note how the message with 'keep: true' is automatically redelivered.
Read more about this at the `HeaderStore` node type, below.
## `mhub-client` commandline interface
The `mhub-client` commandline tool can be used to both listen for messages, or to
publish messages. See `mhub-client --help` for available commandline parameters:
```
$ mhub-client --help
Listen mode:
mhub-client [-n
] -l [-p ] [-o ]
Post mode:
mhub-client [-n ] -t [-d ] [-h ]
Pipe mode:
mhub-client [-n ] -t -i [-h ]
Use -s [protocol://][:] to specify a custom server/port.
To use SSL/TLS, use e.g. -s wss://your_host.
For self-signed certs, see --insecure.
Options:
--help Show help [boolean]
-s, --socket WebSocket to connect to, specify as [protocol://]host[:port],
e.g. ws://localhost:13900, or wss://localhost:13900
[string] [required] [default: "localhost:13900"]
-n, --node Node to subscribe/publish to, e.g. 'test'
[string] [required] [default: "default"]
-l, --listen Select listen mode [boolean]
-p, --pattern Topic subscription pattern as glob, e.g. 'twitter:*' [string]
-o, --output Output format, can be: human, text, jsondata, json
[string] [default: "human"]
-t, --topic Message topic [string]
-d, --data Optional message data as JSON object, e.g. '"a string"' or '{
"foo": "bar" }' [string]
-h, --headers Optional message headers as JSON object, e.g. '{ "my-header":
"foo" }' [string]
-i, --input Read lines from stdin, post each line to server.
can be: text, json [string]
--insecure Disable server certificate validation, useful for testing
using self-signed certificates [boolean]
--key Filename of TLS private key (in PEM format) [string]
--cert Filename of TLS certificate (in PEM format) [string]
--ca Filename of TLS certificate authority (in PEM format) [string]
--passphrase Passphrase for private key [string]
--pfx Filename of TLS private key, certificate and CA certificates
(in PFX or PKCS12 format). Mutually exclusive with --key,
--cert and --ca. [string]
--crl Filename of certificate revocation list (in PEM format)
[string]
--ciphers List of ciphers to use or exclude, separated by : [string]
-U, --username Username [string]
-P, --password Password. Note: sent in plain-text, so only use on secure
connection. Also note it may appear in e.g. `ps` output.
[string]
-v, --version Show version number [boolean]
```
### Listening for messages
Using `mhub-client`, listen mode is initiated with the `-l` parameter.
In the default (human-friendly) format, short messages are printed on a single
line, but larger messages will wrap across multiple lines. See below for options
to change this.
To simply listen for all messages on the `default` topic, use:
```sh
mhub-client -l
```
To listen for all messages on another node use e.g.:
```sh
mhub-client -l -n somenode
```
To only receive messages with a certain topic use e.g.:
```sh
mhub-client -l -n ping -p 'ping:*'
```
(Tip: use the bundled `mhub-ping` program to do a quick round-trip time measurement.)
By default, all messages are printed in a somewhat human-readable format, which
is not suitable for consumption by other programs. However, a number of output
options are available to simplify this:
* `human` (default): Outputs raw messages, but mostly without quotes
* `text`: Outputs just the data field of a message as text. Useful when
listening to a single topic that only contains string data. Note: if data is
an object, it will still be printed in human-readable format, and may thus
span multiple lines.
* `json`: Outputs the full message as JSON. Every message is guaranteed to be
printed on its own line, and contains all info in the message (topic, headers
and data).
* `jsondata`: Outputs just the data field of a message. Every message is
guaranteed to be printed on its own line. Useful when listening to just a
single topic with complex data.
### Publishing single messages
Publishing a single message can be done by specifying the `-t` option (and not
passing `-l` nor `-i`).
To publish a message without data to the `default` topic, use e.g.:
```sh
mhub-client -t test:something
```
Again, the `-n` option can be used to specify a custom node.
```sh
mhub-client -n ping -t ping:request
```
To pass data (and/or headers) to a message, it needs to be specified as JSON.
This means that e.g. a number can be specified directly as e.g. `42`, but a
string needs to be enclosed in double-quotes (e.g. `"something"`).
Note that shells typically parse these quotes too, so they will need to be
escaped.
For example:
```sh
# On *nix shell:
mhub-client -t my:topic -d '"some string"'
mhub-client -t my:topic -d '{ "key": "value" }'
# On Windows command prompt:
mhub-client -t my:topic -d """some string"""
mhub-client -t my:topic -d "{ ""key"": ""value"" }"
```
### Publishing multiple messages / streaming from other programs
It is possible to 'stream' messages to the bus by using the `-i` option.
Available input formats are:
* text: Every line of the input is sent as a string in the message's data field.
* json: Every line of the input is parsed as a JSON object, and used as the
message's data field.
Example to stream tweets into an mhub-server, using the `tweet` command from
`node-tweet-cli`.
```sh
tweet login
tweet stream some_topic --json | mhub-client -t twitter:add -i json
```
### Advanced message routing and transformations
The above examples all use the bundled commandline tools to achieve simple
message routing.
For more advanced scenario's you can use e.g.:
* [MHub for Node-RED](https://github.com/poelstra/node-red-contrib-mhub): a visual programming tool for the Internet of Things
* [mhub-relay](https://github.com/poelstra/mhub-relay): allows you to connect to one or more MHub servers, subscribe to nodes,
optionally transform messages (using simple JavaScript functions), and publish them to other nodes.
## Customizing server nodes and bindings
To customize the available nodes and bindings, create a copy of
`server.conf.json`, edit it to your needs and start the server as:
```sh
mhub-server -c
```
Note: the pattern in a binding can be omitted, in which case everything will
be forwarded.
Note: don't edit the `server.conf.json` file directly, because any changes to it
will be lost when you upgrade `mhub`. Edit a copy of the file instead.
### Debug logging
To assist in debugging message routing, start the server as:
```sh
mhub-server -l debug
```
Or set the `logging` option in the config file to `"debug"`:
```js
// In server.conf.json:
{
"logging": "debug" // or: none, fatal, error, warning, info (default)
}
```
This will show incoming commands, message routing and outgoing commands,
and adds timestamps to each line.
Note: enabling debug mode will slow down message processing, especially
on a Windows console. Don't expect your 60fps mouse tracking to work then.
### Node types
MHub supports different types of nodes.
The default configuration has a node named `default`, which is configured
as a `HeaderStore`. This is likely all you need for many applications.
You can configure custom nodes in the `nodes` property of the server
configuration as an object of `{ node_name: node_definition }` pairs as:
```js
// In server.conf.json:
{
"nodes": {
"nodename1": "TypeWithoutOptions",
"nodename2": {
"type": "TypeWithOptions",
"options": {
/* configuration options for this type of node */
}
}
},
/* rest of configuration file */
}
```
For examples, see the packaged `server.conf.example.json`.
Currently available node types and their options:
* `Exchange`: Simplest node type. Broadcasts any incoming message to all
subscribed clients (taking their pattern into account, of course).
* `HeaderStore`: Forwards all messages (like `Exchange`), but depending on
a message's `keep` header, can also store messages when new subscribers
arrive later, also when the server is restarted.
This is useful for storing the last state of a switch, (simple) configuration
data (e.g. URLs of JSON APIs), etc.
If a message's `keep` header is true, the message will be stored, overwriting
any previously stored message for its topic.
If `keep` is false, previous message for this topic is cleared (but message
is still forwarded).
Note: if `keep` is not present, message will be forwarded, but any previously
stored message (if any) will NOT be affected.
* `persistent?: boolean`: Whether to persist this queue to disk (default
true)
* `Queue`: Forwards incoming messages to all subscribed clients (like an
Exchange), but also stores a configurable number of messages. A new subscriber
will receive all currently stored messages. Useful for e.g. chat applications,
list last X tweets, etc.
Optionally, a pattern can be given to limit which message topics will be
remembered. Additionally, the queue can be persisted to disk, such that it
survives `mhub-server` restarts.
Configuration options:
* `capacity?: number`: Number of messages to keep (default 10)
* `pattern?: string | string[]`: Which messages (filtered by topic) to keep
(default all)
* `persistent?: boolean`: Whether to persist this queue to disk (default
false)
* `TopicStore`: Forwards all messages, but also stores the last message for each
topic. New subscribers will receive that last message (and any future state)
of the topics. Useful for storing (simple) configuration data (e.g. URLs of
JSON APIs), initializing all connecting displays to the same state, etc.
To 'delete' a topic from storage, send a message without any data (payload).
Note: this means that a message will always need to have some sort of data
in order to be stored by a `TopicStore`.
Note: this node is deprecated in favor of the `HeaderStore`.
Again, a topic pattern can be given, and the queue can be persisted to disk.
* `pattern?: string | string[]`: Which messages (filtered by topic) to keep
(default all)
* `persistent?: boolean`: Whether to persist this queue to disk (default
false)
* `ConsoleDestination`: Debug helper that logs all messages published to it, to
the console.
* `PingResponder`: Useful to measure round-trip response times. When it receives
a message with topic `ping:request`, it will respond with a message with topic
`ping:response` and the same payload as it received in the request.
This type of node is set up by default in the packages configuration, on a
node called `ping`.
* `TestSource`: Source of periodic test messages. Configured by default in the
packaged configuration as node `blib`.
* `topic?: string`: Topic for the test messages (default "blib")
* `interval?: number`: Delay between messages (in ms, default 5000)
For backward compatibility, it's also possibly for `nodes` to be an array of
node names, in which case all these nodes are created as `Exchange` nodes.
## Configuring transports (protocols / ports)
`mhub-server` natively supports a JSON-based protocol, which is by default
served over WebSockets (port 13900). It can also be configured for websockets
over https on port 13901.
Additionally, the same JSON-based protocol is also available on a 'raw' TCP
(by default on port 13902), where each protocol command/response is transferred
as one UTF-8 encoded JSON string per line, each line terminated by a newline
(`\n`, ASCII code 10).
This allows easy integration with platforms that don't support WebSockets.
To configure which ports and transports `mhub-server` uses, use the `listen`
field in `server.conf.json`. It accepts either a single object or an array of
objects that describe one or more transports to be used.
See the configuration file and the next section for examples on setting it up.
## Using TLS / SSL
To enable TLS / SSL on the server (`wss://` instead of `ws://`), you can change your
server configuration to look like:
```js
// In server.conf.json:
{
"listen": [
{
"type": ... ...
近期下载者:
相关文件:
收藏者: