我正在使用上下文 API 将相同的 mqtt 连接传递给子组件。问题是,一旦客户端连接到代理(CONNACK),它就会立即关闭并开始永远重新连接。
"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>
);
}
我使用的是 EMQX Serverless,所以无法使用日志。
我检查了端口、主机 URL,并尝试使用 MQTTX 客户端连接到代理,但问题仅出现在我的 web 应用程序中。
问题是 WSS 需要安全连接,但我的本地主机不提供该连接。当我在 Firefox 中将 CA 证书添加到本地主机后,它就开始正常工作了。