Connecting to MyQttHub with MQTT over secure WebSocket (WSS)


#1

Connecting to MyQttHub with MQTT over secure WebSocket (WSS)

The public node node02.myqtthub.com accepts MQTT connections over encrypted WebSocket (WSS) on port 443, the same one the website uses. This adds a third way to connect, alongside the ones already available:

Transport Endpoint What it is for
MQTT node02.myqtthub.com:1883 Devices and servers on a trusted network
MQTT over TLS node02.myqtthub.com:8883 Devices and servers, encrypted
MQTT over WebSocket + TLS wss://node02.myqtthub.com/mqtt Browsers and restrictive networks

When WebSocket is the right choice

There are two cases where it is the only practical option:

  1. From a browser. JavaScript running on a page cannot open a raw TCP socket, so a web panel, a dashboard or any browser application can only speak MQTT through WebSocket.
  2. Behind a restrictive network. Many corporate networks, hotel wifis and mobile connections only allow outbound traffic on 443. Because WSS travels on that port and is indistinguishable from HTTPS traffic, it gets through filters that would block 1883 or 8883.

If your devices sit on a network where you can open 8883, that remains the most direct route. WebSocket adds a small overhead from framing the messages.

Connection details

URL           : wss://node02.myqtthub.com/mqtt
Host          : node02.myqtthub.com
Port          : 443
Path          : /mqtt
Sub protocol  : mqtt
MQTT version  : 3.1.1
Credentials   : the device Client ID, user name and password

The credentials are the same ones you would use on 8883: the Client ID, user name and password of the device registered in your hub. Nothing new has to be created to use WebSocket.

Three details that prevent most of the problems:

  • The /mqtt path is required. Connecting to wss://node02.myqtthub.com/ without it will not work.
  • Use wss://, never ws://. A page served over HTTPS is not allowed to open unencrypted connections: the browser blocks them as mixed content.
  • The sub protocol is mqtt. Almost every library sends it on its own; if your client lets you configure it, that is the value. mqttv3.1 is also accepted for older clients.

The server certificate is a public one (issued by a well known CA), so there is no certificate to install and no need to disable TLS verification.

Example: browser (MQTT.js)

<script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
<script>
  const client = mqtt.connect("wss://node02.myqtthub.com/mqtt", {
    clientId: "myDeviceId",
    username: "myUser",
    password: "myPassword",
    protocolVersion: 4,   // MQTT 3.1.1
    clean: true,
    keepalive: 30
  });

  client.on("connect", () => {
    console.log("Connected");
    client.subscribe("home/livingroom/temperature");
    client.publish("home/livingroom/status", "online");
  });

  client.on("message", (topic, payload) => {
    console.log(topic, payload.toString());
  });

  client.on("error", (err) => console.error("Error:", err));
</script>

Example: Python (paho-mqtt)

import paho.mqtt.client as mqtt

client = mqtt.Client(client_id="myDeviceId", transport="websockets")
client.username_pw_set("myUser", "myPassword")
client.tls_set()                       # public certificate: no parameters
client.ws_set_options(path="/mqtt")

client.connect("node02.myqtthub.com", 443, keepalive=30)
client.loop_forever()

Watch out for two things that often catch people: the port is 443 (not 8883), and the path is configured separately with ws_set_options — it is not part of the host name.

Example: Node.js

const mqtt = require("mqtt");

const client = mqtt.connect("wss://node02.myqtthub.com/mqtt", {
  clientId: "myDeviceId",
  username: "myUser",
  password: "myPassword",
  keepalive: 30
});

client.on("connect", () => client.subscribe("home/#"));
client.on("message", (topic, payload) =>
  console.log(topic, payload.toString()));

Graphical clients

In MQTTX, MQTT Explorer and similar tools, the equivalent settings are:

Protocol / Schema : wss
Host              : node02.myqtthub.com
Port              : 443
Path              : /mqtt
Username / Password : the ones of your device
Client ID         : the one of your device

Checking that the service answers

Without any MQTT client, you can verify the channel with openssl:

printf 'GET /mqtt HTTP/1.1\r\nHost: node02.myqtthub.com\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Protocol: mqtt\r\n\r\n' \
  | openssl s_client -connect node02.myqtthub.com:443 -servername node02.myqtthub.com -quiet 2>/dev/null \
  | head -6

The answer must be:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: mqtt

That 101 confirms the WebSocket channel is established and the mqtt sub protocol is negotiated correctly. From there on, any failure is about credentials or client configuration, not connectivity.

Recommendations and common issues

Set a keepalive between 30 and 60 seconds. A WebSocket connection that goes silent for too long may be closed by intermediate equipment. The MQTT PINGREQ is what keeps it alive; 30 seconds is plenty and costs almost nothing.

Use a unique Client ID per device. If two clients connect with the same Client ID, the second one displaces the first. This is the number one cause of “it keeps disconnecting every few seconds”.

Messages travel inside binary frames. Nothing to configure, but worth knowing: the library takes care of reassembling the MQTT packets, and WebSocket frame boundaries do not necessarily match MQTT message boundaries.

The panel shows your real IP. WebSocket connections appear in the connections list with the mqtt-ws protocol and with the public address they connect from, exactly like those on 1883 or 8883.

If you put your own proxy in front, remember WebSocket needs it to forward the Upgrade and Connection headers. On Apache that means mod_proxy_wstunnel; on nginx, proxy_set_header Upgrade and proxy_set_header Connection "upgrade".

Other nodes

This article describes the service on node02.myqtthub.com. If your hub runs on a different node, the WebSocket endpoint may differ. Write to us and we will confirm the one matching your installation.

Questions, or something not working as expected? Reply in this thread or write to support@myqtthub.com.


WebSockets Support?
MyQttHub EN -- Start here