Hi all, so after some time evaluating and making sense of (where i can) the specification & every piece of information i can find around the internet I have some updates to share...
Foreword
- Many parts of the MQTT V5 additions are covered (but not all). I have listed out most of the features and provided some notes regarding their purpose and status.
- It was not my intention to actually upgrade the MQTT nodes however in testing how they work and fit into node-red, I ended up pretty much doing that so I hope what i have done is of some use.
- A lot of this is a brain dump - please be forgiving
First some demos (ease you in)
Broker Node
Publish node
Subscribe node
User Properties...
Topic alias
Request / Response Pattern
no local (and more user properties / content type)
Shared topics
Details...
Server/Broker options | Implementation notes | Testing | Follow up |
---|---|---|---|
Session expiration. Split the cleanup session flag into a new start flag and the session expiration interval can be modified when disconnected. | number type input. Type checked and coerced into integer before updating v5 properties object | 100% | |
Flow control. Allow the client and server to specify the number of outstanding reliable messages (QoS> 0) respectively | number type input. Type checked and coerced into integer before updating v5 properties object | 50% | Attempted to test by setting low value (5) but couldnt trigger the disconnect. Suspect this is something I am doing wrong in my tests |
Maximum packet length. Allow the client and server to individually specify the maximum message lengths they support | number type input. Type checked and coerced into integer before updating v5 properties object | 50% | Although implemented and tested, it seems a bit odd in that when requesting the msg size to be smaller, a subscription node still receives a message but the topic is empty. So it works but not as expected. |
Reason codes of all confirmation packets. All response packets contain reason codes so that the caller can determine whether the requested function was successful. | Leave for future update | NA | In my trials and testing, the 'message' event never seems to contain this! Perhaps we need to handle 'packet' event instead? |
Optional server function availability. Inform the client the feature list supported by the server to avoid the client using unsupported features | Upon connack, I capture the flags the broker reported. | 50% | Utilise these flags and determine safe defaults. Not necessary for 1st v5 release. Can easily be utilised at a later for a later revision / when requested? |
Enhanced authentication. Provide a mechanism to enable challenge/response style authentication including mutual authentication. | Leave for future update | NA | OK to leave this for a later revision / when requested? |
Server Disconnect. The server is allowed to send a DISCONNECT message to indicate why the connection was closed. | The event is wired up but unsure how to handle it | 50% | What to do with this event? The broker disconnects regardless so its probably for client side cleanup / visualisation / logging only? |
Server reference / redirect. Allows the server to specify a standby server. | Leave for future update | NA | OK to leave this for a later revision / when requested? |
Will delay. Provide the ability to delay the sending of the specified will message after the connection is interrupted | Leave for future update | NA | OK to leave this for a later revision / when requested? |
Server keeps connected. Allow the server to specify the keep-alive values it wants the client to use | Leave for future update | NA | OK to leave this for a later revision / when requested? |
Subscribe options | Implementation notes | Testing | Follow up / notes |
---|---|---|---|
Shared subscription. Load balancing groups (round robin) | Already impliemented | 100% | Round robin tested + working as expected |
Subscription Identifier. Allows to specify a digital subscription identifier in the subscription packet and returns this identifier when the message is distributed | The value is parsed into integer type and passed to the v5 properties object when > 0. | 75% | If a subID is present in an incoming message AND this UI option is set, this acts like a secondary filter and actually solves the multiple messages on overlapping wildcard topics. Is this a reasonable approach for NR implementation? |
no local. Don’t send published messages back to same client | Checkbox flag option. Type checked and coerced into boolean before updating v5 properties object | 100% | |
Retain as Published. Messages forwarded using this subscription keep the RETAIN flag they were published with | Checkbox flag option. Type checked and coerced into boolean before updating v5 properties object | 100% | Works as described (though I am not certain of usefulness the feature). |
Retain Handling. 0: always get retained messages, 1: get retained messages on new subscription, 2: never get retained messages | Select option. Type checked and coerced into integer 0 ~ 2 before updating v5 properties object | 50% | I have verified correct value is passed to v5 properties. Seems to work but needs thought around option 1. |
User Properties. Support user-defined attributes and transmission of additional custom information to expand more application scenarios | Permit JSON and flow/global. Under the hood, a helper function ensures only string pair values are sent / received | 100% | Unsure of the purpose of user properties in the subscribe node! I suspect they arrive in the suback packet for use by other broker/client implementations. |
Publish Options | Implementation notes | Testing | Follow up / notes |
---|---|---|---|
User Properties. Support user-defined attributes and transmission of additional custom information to expand more application scenarios | TypedInput permits JSON and msg/flow/global. Under the hood, a helper function ensures ony string pair values are sent / received | Done | Should this be an editableList (or is typedInput acceptable for initial version) |
Topic alias. Reduce the overhead of MQTT messages by shortening the topic name to a small integer. | Can be passed in msg.topicAlias if empty. NOTE Broker disconnects if topicAlias is used without first being set. This is per spec | Done | Should this be a typed input? (or is std input acceptable in first release) |
Message expiration. Allows messages to be published with an expiration interval | Can be passed in msg.sessionExpiryInterval if empty | Done | Should this be a typed input? (or is std input acceptable in first release) |
Payload format and content type. Allows to specify payload format (binary, text) and MIME-style content types when publishing messages | Can be passed in msg.contentType and msg.payloadFormatIndicator if fields are empty. | 50% | The contentType is simple (passed back in the message) but unsure how to handle utf8. Is the binary/utf8 transmission handled by the client? Cant find clear details |
Request / Response Pattern. Specify the MQTT request / response mode, provide the response topic and compare data attributes, and control the response message to be routed back to the request publisher | Can be passed in msg.responseTopic and and msg.correlationData if fields are empty. | Done | For this implimentation, correlationData must be a buffer (as per spec). however, should we permit string/other value types in correlationData & coerce this to a buffer in the backend? The issue arises when we try to do the reverse on an incoming message. Is it acceptable to leave this as a buffer in first release? |
Shared subscription. support for shared subscriptions to allow load balancing for multiple subscription consumers | Tested 3 client connections and tested the round robin effect. | Done | |
client identifier. If the server has assigned a client identifier, this client identifier is returned to the client. | Leave for future update | NA | Cant find clear information on this. OK to leave this for a later revision / when requested? |
Subscription Identifier. An ID associated with the subscription | The value is parsed into integer type and passed to the v5 properties object when > 0 (as per spec) | Done | I cant for the life of me understand how Sub ID operates at the publish side. Oasis desc on Subscription Identifier for publish packet is unclear. |
Notes
- V5 options are hidden by default and show when a user selects V5 option in the broker config node.
- Publishing or Subscribing with incorrect properties value types or incorrect combinations of values can crash node-red. A few helper functions that check bounds and coerce types were added to contain this.
- Currently, MQTT Node doesn’t unsubscribe a topic until the node is deleted, in order for changed options to take effect, this probably needs changing (in my works I have changed this)
- For publish nodes, the v5 properties that can be sent in msg object use the exact name/case/spelling as the MQTT.JS lib for consistency. However, if all items were typedInputs, this would be moot.
Reference: Oasis Spec
Update
More testing and above info updated.