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": ... ...

近期下载者

相关文件


收藏者