# Node-RED Mqtt 5 support

**URL:** <https://discourse.nodered.org/t/node-red-mqtt-5-support/17847>\
**Category:** General\
**Created:** [12 November 2019 16:43 UTC](https://discourse.nodered.org/t/node-red-mqtt-5-support/17847 "2019-11-12T16:43:27Z")\
**Posts on this page:** 1\
**Showing post:** 24

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [14 October 2020 13:32 UTC](https://discourse.nodered.org/t/node-red-mqtt-5-support/17847/24 "2020-10-14T13:32:04Z")

</div>

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

 ![2020-10-14_14-02-27](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/d/d/ddb9ce7d2bd880262a0e9a5df30c2d289cd0f265.gif)

Publish node

 ![2020-10-14_13-57-56](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/b/e/be47a3f789f8b1536f397bf0f97cbbba1a16ca65.gif)

Subscribe node

 ![2020-10-14_14-26-32](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/8/0/80aa26e03668887a2b945ad114823f7f915faacc.gif)

User Properties...  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/3/d/3d16e5cc79d69a4ca841a505c808c144ba7ea1e6.png)

Topic alias

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/1/a/1ad61b96f993a6d5fdab62f18b8e132cf09f6f85.png)

Request / Response Pattern

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/8/3/83fd5afc654c89a7d6f0ed2782b85edbc963641d.png)

no local (and more user properties / content type)

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/b/9/b9a715a204d083b0c61abc7771205709d5446a99.png)

Shared topics  
 ![2020-10-14_13-17-00](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/7/6/76bae75541e91860667870610b8af34baadd281a.gif)

## 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](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901117) 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](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html)

Update  
More testing and above info updated.

---

_[View the full topic](https://discourse.nodered.org/t/node-red-mqtt-5-support/17847)._
