在TS中使用MQTT

TypeScript 编写的 MQTT 客户端类,包含订阅、发送消息、心跳和断开连接的方法

1,首先安装mqtt

npm install mqtt

2,然后,你可以创建一个 MqttClient.ts 文件,内容如下:

import mqtt, { MqttClient as MqttClientType, IClientOptions } from 'mqtt';

interface MqttClientConfig {
  host: string;
  endpoint: string;
  clientId: string;
  username: string;
  password: string;
  keepalive: number;
  cleanSession: boolean;
  connectTimeout: number;
}

class MqttClient {
  private client: MqttClientType;
  private keepAliveInterval: NodeJS.Timeout | null = null;
  private heartbeatTopic: string = '$heartbeat';

  constructor(config: MqttClientConfig) {
    const { host, endpoint, clientId, username, password, keepalive, cleanSession, connectTimeout } = config;

    // MQTT 连接选项
    const options: IClientOptions = {
      clientId,
      username,
      password,
      keepalive,
      clean: cleanSession,
      connectTimeout,
      will: {
        topic: this.heartbeatTopic,
        payload: 'Client disconnected',
        qos: 0,
      },
    };

    // 连接到 MQTT 代理
    this.client = mqtt.connect(`mqtt://${host}${endpoint}`, options);

    this.client.on('connect', () => {
      console.log('Connected to MQTT broker.');
    });

    this.client.on('error', (err) => {
      console.error('Connection error:', err);
    });

    this.client.on('message', (topic, message) => {
      console.log(`Received message '${message.toString()}' on topic '${topic}'`);
    });

    this.client.on('close', () => {
      console.log('Connection closed.');
    });
  }

  /**
   * 订阅一个主题
   * @param topic 主题名称
   * @param callback 消息处理函数
   */
  public subscribe(topic: string, callback: (topic: string, message: Buffer) => void): void {
    this.client.subscribe(topic, (err) => {
      if (err) {
        console.error(`Failed to subscribe to ${topic}:`, err);
      } else {
        console.log(`Subscribed to ${topic}`);
        this.client.on('message', callback);
      }
    });
  }

  /**
   * 发布消息
   * @param topic 主题名称
   * @param message 消息内容
   * @param qos 服务质量等级
   */
  public publish(topic: string, message: string, qos: number = 0): void {
    this.client.publish(topic, message, { qos }, (err) => {
      if (err) {
        console.error(`Failed to publish message to ${topic}:`, err);
      } else {
        console.log(`Message published to ${topic}`);
      }
    });
  }

  /**
   * 启动心跳机制
   * @param interval 心跳间隔(秒)
   */
  public startHeartbeat(interval: number = 60): void {
    if (this.keepAliveInterval !== null) {
      console.warn('Heartbeat already started.');
      return;
    }
    this.keepAliveInterval = setInterval(() => {
      if (this.client.connected) {
        this.publish(this.heartbeatTopic, 'heartbeat');
      }
    }, interval * 1000);
  }

  /**
   * 停止心跳机制
   */
  public stopHeartbeat(): void {
    if (this.keepAliveInterval !== null) {
      clearInterval(this.keepAliveInterval);
      this.keepAliveInterval = null;
      console.log('Heartbeat stopped.');
    }
  }

  /**
   * 断开连接
   */
  public disconnect(): void {
    this.client.end(true, () => {
      console.log('Disconnected from MQTT broker.');
    });
  }
}

export default MqttClient;

到这一步就已经完成了

3,src 目录下创建一个 mqttProvider.ts 文件,用于设置 MQTT 客户端的提供者。

在 Vue 3 中,你可以使用全局状态管理来确保 MQTT 客户端只连接一次,并在多个页面之间共享这个连接。下面是一个

import { reactive, provide, inject } from 'vue';
import MqttClient, { MqttClientConfig } from './MqttClient';

const MQTT_CLIENT_SYMBOL = Symbol('MqttClient');

/**
 * 创建 MQTT 客户端实例并提供
 * @param config MQTT 配置对象
 * @returns 客户端实例及其符号
 */
export function createMqttClient(config: MqttClientConfig) {
  const mqttClient = new MqttClient(config);
  const state = reactive({ client: mqttClient });

  return {
    mqttClient: state,
    MQTT_CLIENT_SYMBOL,
  };
}

/**
 * 获取 MQTT 客户端实例
 * @returns MQTT 客户端实例
 */
export function useMqttClient() {
  const mqttClient = inject(MQTT_CLIENT_SYMBOL);
  if (!mqttClient) {
    throw new Error('No MqttClient provided!');
  }
  return mqttClient as { client: MqttClient };
}

示例:使用 Vue 3 的 provideinject 功能来实现这一点的示例:

App.vue 中,提供 MQTT 客户端配置。

<template>
  <router-view />
</template>

<script setup>
import { createMqttClient } from './mqttProvider';

const mqttConfig = {
  host: '',//地址
  endpoint: '/mqtt',
  clientId: 'your-client-id',
  username: 'your-username',
  password: 'your-password',
  keepalive: 60,
  cleanSession: false,
  connectTimeout: 5000,
};

// 创建并提供 MQTT 客户端实例
const { mqttClient, MQTT_CLIENT_SYMBOL } = createMqttClient(mqttConfig);

// 提供 MQTT 客户端实例给 Vue 组件
provide(MQTT_CLIENT_SYMBOL, mqttClient);
</script>

子组件中获取并使用 MQTT 客户端实例:

<template>
  <div>
    <button @click="sendMessage">Send Message</button>
  </div>
</template>

<script setup>
import { useMqttClient } from '../mqttProvider';

const { client } = useMqttClient();

function sendMessage() {
  client.publish('test/topic', 'Hello from Vue!');
}

// 启动心跳(可选)
// client.startHeartbeat();

// 停止心跳(可选)
// client.stopHeartbeat();

// 断开连接(可选)
// client.disconnect();
</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值