WSS MQTT 连接在连接到 NextJS 中的代理后立即关闭

问题描述 投票:0回答:1

我正在使用上下文 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>
    );

}

这是客户端的输出 Browser console output

我使用的是 EMQX Serverless,所以无法使用日志。

我检查了端口、主机 URL,并尝试使用 MQTTX 客户端连接到代理,但问题仅出现在我的 web 应用程序中。

next.js websocket mqtt emqx
1个回答
0
投票

问题是 WSS 需要安全连接,但我的本地主机不提供该连接。当我在 Firefox 中将 CA 证书添加到本地主机后,它就开始正常工作了。

© www.soinside.com 2019 - 2024. All rights reserved.