For AWS IoT wss connections urls require Sigv4 signing. These urls seemingly expire, so eventually reconnect doesn't work and you need a fresh signature.
You can see here usage of an old version of mqtt.js: https://github.com/aws/aws-iot-device-sdk-js/blob/master/device/index.js#L502-L521
I'm using mqtt.js 2.x directly and my own url signer implementation.
I will possibly get around to a pull request but first would like to see how do people feel about adding an urlSigner function to the connection options, passed along to the stream builder[s]?
I'm more keen on passing a function to connect that will return the URL (or call a callback with an URL).
If that simplifies things for SDKs, then let's go for it.
Something like:
interface Options {}
class MqttClient {}
type urlCallback = (err: Error, url: string) => void
type asyncUrlBuilder (cb: urlCallback) => void
type urlBuilder = () => string | asyncUrlBuilder
type url = string | urlBuilder
function connect(url : url, options: Options) => MqttClient
?
/**
* connect - connect to an MQTT broker.
*
* @param {String} [brokerUrl] - url of the broker, optional
* @param {Object} opts - see MqttClient#constructor
*/
function connect (brokerUrl, opts) {
Hrmmm
IMO it would probably be simplest to just add a function (through the opts) that synchronously transforms the url passed to websocket() each time, here:
https://github.com/mqttjs/MQTT.js/blob/master/lib/connect/ws.js#L99
and here:
https://github.com/mqttjs/MQTT.js/blob/master/lib/connect/ws.js#L45
How would folks feel about a PR adding an async version of this function, so that URLs could be signed remotely? For AWS ioT in particular, this would allow you to ensure an approved clientId and eliminate the need for a local crypto implementation.
@jed if it does not add too much complexity, sure!
Async version would definitely help as the link is normally generated on the server side rather than client.
I managed to code around the need for an async transformWsUrl
Use the error event
client.on('error', (err) => {
// error code 5, Connection refused: Not authorized
if (err.code === 5) {
// token may have expired so try to get a new one
// insert http get here to grab new token
// then set a token variable that is accessible in the scope of your transformWsUrl function
}
}
Most helpful comment
Async version would definitely help as the link is normally generated on the server side rather than client.