I am using the context API to pass the same mqtt connection to child components. The problem is that as soon as the client connects to the broker (CONNACK), it immediately closes and starts reconnecting forever.
"use client";
import * as mqtt from "mqtt";
import React, {createContext, useEffect, useState} from "react";
interface MQTTContextType {
client: mqtt.MqttClient | null,
clientID: string,
}
export const MQTTContext = createContext({} as MQTTContextType);
const MQTT_URL = `wss://${process.env.NEXT_PUBLIC_EMQX_HOST}:${process.env.NEXT_PUBLIC_EMQX_PORT}/mqtt`;
export default function MQTTProvider ({ clientID,
children,}: { clientID: string, children: React.ReactNode }){
const [client, setClient] = useState<mqtt.MqttClient | null>(null);
const MQTTOptions = {
clientId: clientID,
username: process.env.NEXT_PUBLIC_EMQX_USERNAME,
password: process.env.NEXT_PUBLIC_EMQX_PASSWORD,
keepAlive: 30,
}
useEffect(() => {
if (client) {
client.on("connect", () => {
console.log("connected");
//subscribe to test-mqtt topic
client?.subscribe("test-mqtt", (err) => {
if(err){
console.log("error subscribing to test-mqtt topic", err);
}
});
});
client.on("error", (err) => {
console.log("error", err);
});
client.on("reconnect", () => {
console.log("reconnecting");
});
client.on("close", () => {
console.log("closed");
});
client.on("disconnect", () => {
console.log("disconnected");
});
//on end
client.on("end", () => {
console.log("ended");
});
//listen to test topic
client.on("message", (topic, message) => {
console.log("message received", topic, message.toString());
});
//listeen to packet
client.on("packetsend", (packet) => {
console.log("packet sent", packet);
});
//listen to packetreceive
client.on("packetreceive", (packet) => {
console.log("packet received", packet);
});
//no we manually ping the broker
const pingInterval = window.setInterval(() => {
console.log("pinging")
client.publish("ping", "ping "+ Date.now(), (err) => {
if(err){
console.log("error publishing ping", err);
}
});
}, 1000*30); //every 30 seconds
return () => {
client?.end();
window.clearInterval(pingInterval);
}
} else {
setClient(mqtt.connect(MQTT_URL, MQTTOptions));
}
}, [client, clientID]);
const contextValue = {
client,
clientID
};
return (
<MQTTContext.Provider value={contextValue}>
{children}
</MQTTContext.Provider>
);
}
This is the output from the client
I am using EMQX Serverless so I cannot use logs.
I checked the port, the host url and also tried connecting to the broker using MQTTX client, but the problem only occurs in my webapp.
The problem was that WSS needed a secure connection which was not available in my localhost. Once I added a CA cert to localhost in firefox, it started working properly.