import type { MqttClient, IClientOptions } from "mqtt"; import MQTT from "mqtt"; import { useEffect, useRef } from "react"; interface useMqttProps { uri: string; options?: IClientOptions; topicHandlers?: { topic: string; handler: (payload: any) => void }[]; onConnectedHandler?: (client: MqttClient) => void; } function useMqtt({ uri, options = {}, topicHandlers = [{ topic: "", handler: ({ topic, payload, packet }) => {} }], onConnectedHandler = (client) => {}, }: useMqttProps) { const clientRef = useRef(null); useEffect(() => { if (clientRef.current) return; if (!topicHandlers || topicHandlers.length === 0) return () => {}; try { clientRef.current = options ? MQTT.connect(uri, options) : MQTT.connect(uri); } catch (error) { console.error("error", error); } const client = clientRef.current; topicHandlers.forEach((th) => { client?.subscribe(th.topic); }); client?.on("message", (topic: string, rawPayload: any, packet: any) => { const th = topicHandlers.find((t) => t.topic === topic); let payload; try { payload = JSON.parse(rawPayload); } catch { payload = rawPayload; } if (th) th.handler({ topic, payload, packet }); }); client?.on("connect", () => { if (onConnectedHandler) onConnectedHandler(client); }); return () => { if (client) { topicHandlers.forEach((th) => { client.unsubscribe(th.topic); }); client.end(); } }; // eslint-disable-next-line react-hooks/exhaustive-deps }, []); } export default useMqtt;