correct way to instantiate Paho Client in JavaScript for wss (secure websocket)

The Paho documentation is unfortunately quite fragmented at the moment, and some links on Eclipse’s website do not work.

Here are some working links (as of 05/2019):

And here’s a fantastic website by Steve:

There is an important breaking change in the Paho namespace, where you will run into trouble using Steve’s code:

“Previously the Client’s Namepsace was Paho.MQTT, as of version 1.1.0 (develop branch) this has now been simplified to Paho. You should be able to simply do a find and replace in your code to resolve this, for example all instances of Paho.MQTT.Client will now be Paho.Client and Paho.MQTT.Message will be Paho.Message.” (as seen on GitHub)

As the text says, use Paho.Client instead of Paho.MQTT.Client and Paho.Message instead of Paho.MQTT.Message.

Another problem I faced was the inability of the client to connect on wss:// (secure websockets). You need to use a special syntax for that.

TL;DR forcing WSS with Paho:

The syntax is:

mqtt = new Paho.Client(“wss://key:[email protected]/mqtt”, “clientid”);

Note that we do NOT pass in any port. The port is optional and has to be set as part of the URI. Replace the key:[email protected] part with your own URL. /mqtt is default, and also configured on VerneMQ for websockets that way.

The client id has to be a string.

Errors

Here are some wrong (!) code samples and the errors you will run with into them:

The page at ‘https://picockpit.local/debugpaho’ was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint ‘ws://picockpit.local:443/mqtt’. This request has been blocked; this endpoint must be available over WSS.

This is when you assume that Paho will auto-detect the correct protocol for you, if you load over HTTPS. It won’t. You have to pass in an URI to Paho.Client (see above).

The URL ‘ws://[wss://picockpit.local/mqtt]:0’ is invalid. Error: Failed to construct ‘WebSocket’: The URL ‘ws://[wss://picockpit.local/mqtt]:0’ is invalid.

This is when you try to pass in all the parameters – omit all the other parameters, just pass in the clientid (a string). (I tried to set the port to 0 as I thought it will be ignored).

jQuery.Deferred exception: Cannot read property ‘Client’ of undefined TypeError: Cannot read property ‘Client’ of undefined

mqtt = new Paho.MQTT.Client(uri, 0, “”, “myclientid”);

This will happen if you do not replace Paho.MQTT.Client with Paho.Client as advised above.

jquery.min.js:2 Uncaught Error: AMQJS0012E Invalid type object for port.

at new Client (paho-mqtt.min.js:62)

at MQTTconnect (pcp-code.js:17)

at run (debugpaho:133)

at HTMLDocument.<anonymous> (debugpaho:137)

at l (jquery.min.js:2)

at c (jquery.min.js:2)

mqtt = new Paho.Client(“wss://key:[email protected]”);

Confusingly, this is telling us to pass in a port. Maybe the matching for a full URI is by matching for a trailing slash after the hostname as well?

mqtt = new Paho.Client(“wss://key:[email protected]/mqtt”, 443);

jquery.min.js:2 Uncaught Error: AMQJS0013E Invalid argument 443 for clientId.

WebSocket connection to ‘wss://key:[email protected]/mqtt’ failed: Error during WebSocket handshake: Unexpected response code: 403

Finally, this is a correct way to connect to Paho via MQTT. The error code is due to the backend not working as expected (this is not a problem due to Paho).