From 5b60918d75a4b9b03a61c1b1cb3f0ba6b78e4daa Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Fri, 9 Mar 2018 13:03:33 +0000 Subject: [PATCH] Updated Runtime Editor Comms protocol (markdown) --- Runtime-Editor-Comms-protocol.md | 122 ++++++++++++++++++++++++++++++- 1 file changed, 119 insertions(+), 3 deletions(-) diff --git a/Runtime-Editor-Comms-protocol.md b/Runtime-Editor-Comms-protocol.md index 867ce43..a283569 100644 --- a/Runtime-Editor-Comms-protocol.md +++ b/Runtime-Editor-Comms-protocol.md @@ -1,7 +1,123 @@ -The editor establishes a WebSocket connection back to the runtime in order to receive realtime events. +The editor establishes a WebSocket connection back to the runtime in order to receive realtime events. It is *not* used to send control messages to the runtime; it is used for send events to the editor. Any sort of control message is done via the HTTP API. This page documents the protocol used. + - [Message structure](#message-structure) + - [Authentication](#authentication) + - [Subscribe events](#subscribe-events) + - [Runtime events](#runtime-events) + - [Status](#status) + - [Notifications](#notifications) + - [Debug](#debug) + +### Message structure + +All messages passed over the WebSocket are simple JSON strings. Aside from the authentication messages, each message has a `topic` and `data` property. + +### Authentication + +If `adminAuth` is enabled in the runtime, the WebSocket connection must go through an application-level authentication flow before any other data can be sent or received. + +After the WebSocket connection is established, the editor must send an auth packet containing its auth token. + +``` +Editor ---> { auth: "" } ---> Runtime +``` + +The Runtime checks the token and if it is valid and returns: + +``` +Editor <--- { auth: "ok" } <--- Runtime +``` + +If the token is invalid, it returns the following packet and closes the websocket: + +``` +Editor <--- { auth: "fail" } <--- Runtime +``` + +If `adminAuth` is enabled and the first packet the received is not an `auth` packet, the runtime checks whether `adminAuth` has been configured with a default user and whether that user has the necessary permissions. If not, the connection is closed. In either case, no `auth` response packet is sent. + + +### Subscribe events + +After the editor establishes its comms link (and completes authentication) it then sends a set of 'subscribe' packets for the topics it cares about. + +The original concept was for it to use very light-weight MQTT-like semantics for doing publish/subscribe. In reality, we never had a requirement for when an editor would unsubscribe from a topic. The end result is the editor will receive all messages regardless of whether they are subscribed or not. + +But what the subscribe message does do is trigger the runtime to send any `retained` messages on those topics. This allows the editor to receive the last-known state for certain topics. + +``` +Editor ---> { subscribe: "" } ---> Runtime +``` + +The `topic` can use MQTT wildcards; `+` and `#` to pattern match. + + +### Runtime events + + +#### Status + +Status events come from individual nodes calling the [Node Status API](https://nodered.org/docs/creating-nodes/status) + +``` +Editor <--- { topic: "status/", data: {} } <--- Runtime +``` + +The `topic` includes the ID of the node. The data payload is the status object described in the [Node Status API](https://nodered.org/docs/creating-nodes/status). + +#### Notifications + +Notification events come from the runtime and indicate an event or change of state within the runtime. + +``` +Editor <--- { topic: "notification/", data: {} } <--- Runtime +``` + +The current list of runtime notifications are as follows. *Their full payload contents needs documenting.* + + - `node/enabled` - a node-set has been enabled via `/node` admin api + - `node/disabled` - a node-set has been disabled via `/node` admin api + - `node/added` - a node-set has been added via `/node` admin api + - `node/removed` - a node-set has been removed via `/node` admin api + - `node/upgraded` - a node-set has been upgraded via `/node` admin api + - `project-update` - the active project has been updated and should be refreshed in the editor + - `restart-required` - the runtime requires a manual restart - normally due to removing or upgrading a node + - `runtime-redeploy` - new flows have been deployed to the runtime + - `runtime-state` - a change to the state of the runtime. If the runtime has stopped due to an error state, the payload will have an `error` property to indicate the cause. Possible values are: + - `credentials_load_failed` - failed to decrypt the credentials file + - `missing-types` - the flow uses node types that are not present in the runtime + - `git_merge_conflict` - the active project is in the middle of a merge conflict + - `missing_flow_file` - the active project does not identify a flow file to use + - `project_empty` - the active project is empty + - `runtime-unsupported-version` - the node.js is old. Too Old. + + +### Debug + +The Debug node is an example of a node that makes use of Comms. In general we have *not* documented or encouraged 3rd party nodes to use comms. + +The Debug node will publish a message when it receives a message within a flow. It also registers a log handler and publishes any WARN or ERROR messages so they will appear in the debug sidebar. + +Debug messages are published to the `debug` topic. + +``` +Editor <--- { topic: "debug", data: {} } <--- Runtime +``` + +The full format of the Debug message needs documenting. + +``` +{ + id: , + name: , + topic: , + msg: , +} +``` + +Some further encoding of the `msg` being passed to Debug is done. It handles Buffers and other non-JSON encodable types, and also truncates big objects whilst maintaining their metadata so the Debug sidebar can indicate how big they were before being truncated. + + - - Authentication - - Message structure