I have a eclipse-mosquitto container running on a server which I want to connect to over wss
.
I have the following configuration on the server
allow_anonymous false
password_file /mosquitto/config/passwd
persistence true
persistence_location /mosquitto/data/
log_type all
log_dest file /mosquitto/log/mosquitto.log
log_dest stdout
listener 1883
protocol mqtt
listener 8083
protocol websockets
websockets_log_level all
socket_domain ipv4
listener 8883
protocol mqtt
require_certificate false
cafile /mosquitto/cert/ca.crt
certfile /mosquitto/cert/server.crt
keyfile /mosquitto/cert/server.key
tls_version tlsv1.2
listener 8084
protocol websockets
require_certificate false
cafile /mosquitto/cert/ca.crt
certfile /mosquitto/cert/server.crt
keyfile /mosquitto/cert/server.key
tls_version tlsv1.2
websockets_log_level all
socket_domain ipv4
user mosquitto
And the following docker-compose config
mosquitto:
container_name: mosquitto
image: eclipse-mosquitto:latest
restart: unless-stopped
hostname: "${ENV_TYPE}-mosquitto"
ports:
- 1883:1883
- 8883:8883
- 8083:8083
- 8084:8084
volumes:
- ./volumes/mosquitto/data:/mosquitto/data
- ./volumes/mosquitto/log:/mosquitto/log
- ./volumes/mosquitto/config:/mosquitto/config
- ./volumes/mosquitto/cert:/mosquitto/cert
And using MQTT Explorer I am able to connect just fine over tls
But when trying to connect to it using the mqtt.js library I fail to get a wss
connection. ws
over port 8083
works just fine, just as connecting to a a different broker over wss
.
<body>
<script src="https://unpkg.com/mqtt/dist/mqtt.js"></script>
<script>
const id = Math.random().toString(36).substring(7);
const topic = "topic";
const connection = "wss://username:password@37.97.203.138:8084"
// const connection = "ws://username:password@37.97.203.138:8083" // Works
// const connection = "wss://public:public@public.cloud.shiftr.io" // Works
const client = mqtt.connect(connection, {
rejectUnauthorized: false,
});
client.on("message", messageReceived);
client.on("connect", function () {
println("connected!");
client.subscribe("topic");
client.publish("topic", "Hello from HTML");
});
client.on("error", function (error) {
println("Error: " + error);
});
client.on('end', function() {
println("Disconnected");
})
function messageReceived(topic, message) {
println(topic + ": " + message);
}
function println(message) {
const p = document.createElement("p");
p.textContent = message;
document.querySelector("body").append(p);
}
</script>
</body>
edit:
The mosquito logs are not showing anything on these connection attempts.
from this post I added localStorage.debug = 'mqttjs*'
to get more logging.
Which gave me these logs
mqttjs connecting to an MQTT broker... +0ms
mqtt.js:10115 mqttjs:client MqttClient :: version: +0ms 5.4.0
mqtt.js:10115 mqttjs:client MqttClient :: environment +0ms browser
mqtt.js:10115 mqttjs:client MqttClient :: options.protocol +0ms wss
mqtt.js:10115 mqttjs:client MqttClient :: options.protocolVersion +0ms 4
mqtt.js:10115 mqttjs:client MqttClient :: options.username +1ms mdd
mqtt.js:10115 mqttjs:client MqttClient :: options.keepalive +0ms 60
mqtt.js:10115 mqttjs:client MqttClient :: options.reconnectPeriod +0ms 5000
mqtt.js:10115 mqttjs:client MqttClient :: options.rejectUnauthorized +0ms false
mqtt.js:10115 mqttjs:client MqttClient :: options.properties.topicAliasMaximum +0ms undefined
mqtt.js:10115 mqttjs:client MqttClient :: clientId +0ms 4zjpti
mqtt.js:10115 mqttjs:client MqttClient :: setting up stream +0ms
mqtt.js:10115 mqttjs:client connect :: calling method to clear reconnect +0ms
mqtt.js:10115 mqttjs:client _clearReconnect : clearing reconnect timer +0ms
mqtt.js:10115 mqttjs:client connect :: using streamBuilder provided to client to create stream +0ms
mqtt.js:10115 mqttjs calling streambuilder for +1ms wss
mqtt.js:10115 mqttjs:ws browserStreamBuilder +0ms
mqtt.js:10115 mqttjs:client connect :: pipe stream to writable stream +1ms
mqtt.js:10115 mqttjs:client connect: sending packet `connect` +0ms
mqtt.js:10115 mqttjs:client _writePacket :: packet: Object +0ms
mqtt.js:10115 mqttjs:client _writePacket :: emitting `packetsend` +0ms
mqtt.js:10115 mqttjs:client _writePacket :: writing to stream +0ms
mqtt.js:10115 mqttjs:client _writePacket :: writeToStream result true +8ms
mqtt.js:21161 WebSocket connection to 'wss://37.97.203.138:8084/' failed:
createBrowserWebSocket @ mqtt.js:21161
browserStreamBuilder @ mqtt.js:21185
wrapper @ mqtt.js:21398
connect @ mqtt.js:17840
_MqttClient @ mqtt.js:17816
connect @ mqtt.js:21400
(anonymous) @ examples/:13
mqtt.js:10115 mqttjs:ws WebSocket onError +21ms Event {isTrusted: true, type: 'error', target: WebSocket, currentTarget: WebSocket, eventPhase: 2, …}
mqtt.js:10115 mqttjs:ws WebSocket onClose +1ms CloseEvent {isTrusted: true, wasClean: false, code: 1006, reason: '', type: 'close', …}
mqtt.js:10115 mqttjs:client streamErrorHandler :: error +13ms WebSocket error
mqtt.js:10115 mqttjs:client noop :: +0ms Error: WebSocket error
at WebSocket.onError (mqtt.js:21235:25)
examples/:27 error Error: WebSocket error
at WebSocket.onError (mqtt.js:21235:25)
mqtt.js:10115 mqttjs:client end :: (4zjpti) +0ms
mqtt.js:10115 mqttjs:client end :: cb? false +0ms
mqtt.js:10115 mqttjs:client _clearReconnect : clearing reconnect timer +0ms
mqtt.js:10115 mqttjs:client end :: (4zjpti) :: immediately calling finish +0ms
mqtt.js:10115 mqttjs:client end :: (4zjpti) :: finish :: calling _cleanUp with force false +0ms
mqtt.js:10115 mqttjs:client _cleanUp :: done callback provided for on stream close +0ms
mqtt.js:10115 mqttjs:client _cleanUp :: forced? false +0ms
mqtt.js:10115 mqttjs:client _cleanUp :: (4zjpti) :: call _sendPacket with disconnect packet +0ms
mqtt.js:10115 mqttjs:client _sendPacket :: (4zjpti) :: start +0ms
mqtt.js:10115 mqttjs:client _sendPacket :: client not connected. Storing packet offline. +0ms
mqtt.js:10115 mqttjs:client _storePacket :: packet: {cmd: 'disconnect'} +0ms
mqtt.js:10115 mqttjs:client _storePacket :: cb? true +0ms
mqtt.js:10115 mqttjs:client _cleanUp :: (4zjpti) :: removing stream `done` callback `close` listener +0ms
mqtt.js:10115 mqttjs:client end :: finish :: calling process.nextTick on closeStores +1ms
mqtt.js:10115 mqttjs:client (4zjpti)stream :: on close +0ms
mqtt.js:10115 mqttjs:client _flushVolatile :: deleting volatile messages from the queue and setting their callbacks as error function +0ms
mqtt.js:10115 mqttjs:client stream: emit close to MqttClient +0ms
mqtt.js:10115 mqttjs:client close :: connected set to `false` +0ms
mqtt.js:10115 mqttjs:client close :: clearing connackTimer +0ms
mqtt.js:10115 mqttjs:client close :: clearing ping timer +0ms
mqtt.js:10115 mqttjs:client close :: calling _setupReconnect +0ms
mqtt.js:10115 mqttjs:client _setupReconnect :: doing nothing... +0ms
mqtt.js:10115 mqttjs:client end :: closeStores: closing incoming and outgoing stores +0ms
mqtt.js:10115 mqttjs:client end :: closeStores: emitting end +0ms
mqtt.js:10115 mqttjs:client end :: closeStores: invoking callback with args +0ms
mqtt.js:10115 mqttjs:client noop :: +0ms undefined
and logging when connecting to wss://public:public@public.cloud.shiftr.io
mqttjs connecting to an MQTT broker... +0ms
mqtt.js:10115 mqttjs:client MqttClient :: version: +0ms 5.4.0
mqtt.js:10115 mqttjs:client MqttClient :: environment +0ms browser
mqtt.js:10115 mqttjs:client MqttClient :: options.protocol +0ms wss
mqtt.js:10115 mqttjs:client MqttClient :: options.protocolVersion +0ms 4
mqtt.js:10115 mqttjs:client MqttClient :: options.username +0ms public
mqtt.js:10115 mqttjs:client MqttClient :: options.keepalive +0ms 60
mqtt.js:10115 mqttjs:client MqttClient :: options.reconnectPeriod +0ms 5000
mqtt.js:10115 mqttjs:client MqttClient :: options.rejectUnauthorized +0ms false
mqtt.js:10115 mqttjs:client MqttClient :: options.properties.topicAliasMaximum +0ms undefined
mqtt.js:10115 mqttjs:client MqttClient :: clientId +0ms qfuu3r
mqtt.js:10115 mqttjs:client MqttClient :: setting up stream +0ms
mqtt.js:10115 mqttjs:client connect :: calling method to clear reconnect +0ms
mqtt.js:10115 mqttjs:client _clearReconnect : clearing reconnect timer +0ms
mqtt.js:10115 mqttjs:client connect :: using streamBuilder provided to client to create stream +0ms
mqtt.js:10115 mqttjs calling streambuilder for +1ms wss
mqtt.js:10115 mqttjs:ws browserStreamBuilder +0ms
mqtt.js:10115 mqttjs:client connect :: pipe stream to writable stream +1ms
mqtt.js:10115 mqttjs:client connect: sending packet `connect` +0ms
mqtt.js:10115 mqttjs:client _writePacket :: packet: Object +0ms
mqtt.js:10115 mqttjs:client _writePacket :: emitting `packetsend` +0ms
mqtt.js:10115 mqttjs:client _writePacket :: writing to stream +0ms
mqtt.js:10115 mqttjs:client _writePacket :: writeToStream result true +15ms
examples/:1 Unchecked runtime.lastError: The message port closed before a response was received.
mqtt.js:10115 mqttjs:ws WebSocket onOpen +309ms
mqtt.js:10115 mqttjs:client writable stream :: parsing buffer +310ms
mqtt.js:10115 mqttjs:client parser :: on packet push to packets array. +1ms
mqtt.js:10115 mqttjs:client work :: getting next packet in queue +0ms
mqtt.js:10115 mqttjs:client work :: packet pulled from queue +0ms
mqtt.js:10115 mqttjs:client _handlePacket :: emitting packetreceive +0ms
mqtt.js:10115 mqttjs:client _handleConnack +0ms
mqtt.js:10115 mqttjs:client _setupPingTimer :: keepalive 60 (seconds) +0ms
mqtt.js:10115 mqttjs:client connect :: sending queued packets +2ms
mqtt.js:10115 mqttjs:client deliver :: entry undefined +0ms
mqtt.js:10115 mqttjs:client _resubscribe +0ms
mqtt.js:10115 mqttjs:client subscribe: array topic qfuu3r +0ms
mqtt.js:10115 mqttjs:client subscribe: pushing topic `qfuu3r` and qos `2` to subs list +0ms
mqtt.js:10115 mqttjs:client subscribe :: resubscribe true +0ms
mqtt.js:10115 mqttjs:client subscribe :: call _sendPacket +0ms
mqtt.js:10115 mqttjs:client _sendPacket :: (qfuu3r) :: start +0ms
mqtt.js:10115 mqttjs:client _writePacket :: packet: Object +0ms
mqtt.js:10115 mqttjs:client _writePacket :: emitting `packetsend` +0ms
mqtt.js:10115 mqttjs:client _writePacket :: writing to stream +0ms
mqtt.js:10115 mqttjs:client _writePacket :: writeToStream result true +1ms
mqtt.js:10115 mqttjs:client _writePacket :: invoking cb +0ms
mqtt.js:10115 mqttjs:client noop :: +0ms undefined
mqtt.js:10115 mqttjs:client subscribe: array topic topic +0ms
mqtt.js:10115 mqttjs:client subscribe: pushing topic `topic` and qos `0` to subs list +0ms
mqtt.js:10115 mqttjs:client subscribe :: resubscribe true +0ms
mqtt.js:10115 mqttjs:client subscribe :: call _sendPacket +0ms
mqtt.js:10115 mqttjs:client _sendPacket :: (qfuu3r) :: start +0ms
mqtt.js:10115 mqttjs:client _writePacket :: packet: Object +0ms
mqtt.js:10115 mqttjs:client _writePacket :: emitting `packetsend` +0ms
mqtt.js:10115 mqttjs:client _writePacket :: writing to stream +0ms
mqtt.js:10115 mqttjs:client _writePacket :: writeToStream result true +0ms
mqtt.js:10115 mqttjs:client _writePacket :: invoking cb +0ms
mqtt.js:10115 mqttjs:client noop :: +0ms undefined
mqtt.js:10115 mqttjs:client publish :: message `Hello from HTML` to topic `topic` +0ms
mqtt.js:10115 mqttjs:client publish :: qos +0ms 0
mqtt.js:10115 mqttjs:client MqttClient:publish: packet cmd: publish +0ms
mqtt.js:10115 mqttjs:client _sendPacket :: (qfuu3r) :: start +0ms
mqtt.js:10115 mqttjs:client _writePacket :: packet: Object +0ms
mqtt.js:10115 mqttjs:client _writePacket :: emitting `packetsend` +0ms
mqtt.js:10115 mqttjs:client _writePacket :: writing to stream +0ms
mqtt.js:10115 mqttjs:client _writePacket :: writeToStream result false +1ms
mqtt.js:10115 mqttjs:client _writePacket :: invoking cb +0ms
mqtt.js:10115 mqttjs:client noop :: +0ms undefined
mqtt.js:10115 mqttjs:client _sendPacket :: (qfuu3r) :: end +0ms
mqtt.js:10115 mqttjs:client writable stream :: parsing buffer +25ms
3mqtt.js:10115 mqttjs:client parser :: on packet push to packets array. +0ms
mqtt.js:10115 mqttjs:client work :: getting next packet in queue +1ms
mqtt.js:10115 mqttjs:client work :: packet pulled from queue +0ms
mqtt.js:10115 mqttjs:client _handlePacket :: emitting packetreceive +0ms
mqtt.js:10115 mqttjs:client _handleAck :: packet type +0ms suback
mqtt.js:10115 mqttjs:client noop :: +0ms null
mqtt.js:10115 mqttjs:client work :: getting next packet in queue +0ms
mqtt.js:10115 mqttjs:client work :: packet pulled from queue +0ms
mqtt.js:10115 mqttjs:client _handlePacket :: emitting packetreceive +0ms
mqtt.js:10115 mqttjs:client _handleAck :: packet type +0ms suback
mqtt.js:10115 mqttjs:client noop :: +0ms null
mqtt.js:10115 mqttjs:client work :: getting next packet in queue +0ms
mqtt.js:10115 mqttjs:client work :: packet pulled from queue +0ms
mqtt.js:10115 mqttjs:client _handlePacket :: emitting packetreceive +0ms
mqtt.js:10115 mqttjs:client handlePublish: packet Packet {cmd: 'publish', retain: false, qos: 0, dup: false, length: 22, …} +0ms
mqtt.js:10115 mqttjs:client handlePublish: qos 0 +0ms
When using MQTT over WebSockets in the browser, the browser handles ALL the TLS work.
The browser will also NOT prompt the user to accept an untrusted certificate for any connection made by the JavaScript code, unlike how it prompts when accessing a webpage.
This means that the browser must trust any certificate that is used to protect a MQTT over WebSockets connection.
This means you have 2 choices: