mqtt.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import { ElMessage } from 'element-plus'
  2. import mqtt, { MqttClient, IClientOptions, IClientSubscribeOptions } from 'mqtt' // 静态导入 mqtt
  3. // 定义 MQTT 配置类型接口
  4. interface MqttConfig {
  5. host: string
  6. options: IClientOptions
  7. topic: string
  8. }
  9. // 定义消息回调函数类型
  10. type MessageCallback = (data: { topic: string; message: Record<string, any> }) => void
  11. // MQTT 连接配置
  12. const MQTT_CONFIG: MqttConfig = {
  13. // 替换为你的 MQTT 服务器地址(ws/wss 协议)
  14. host: 'ws://172.21.10.65:8083/mqtt',
  15. // MQTT 连接选项
  16. options: {
  17. username: 'yanfan', // 替换为你的用户名(无则省略)
  18. password: 'eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjY0YmM2NjJlLWZhMjQtNGY1Ny1hOTk1LWZiMGM2YjNhYzI4OCJ9.9nxoDUNGTk1szRlZHHG0AcWZctLrzJ16UA5rsBagHNcD10PC-LIMTgAr2CK1Ppafa6cW5XPdn7RqBF6iZjHtww', // 替换为你的密码(无则省略)
  19. clean: true,
  20. reconnectPeriod: 5000, // 重连间隔 5 秒
  21. clientId: 'web-' + Math.random().toString(16).substr(2),
  22. connectTimeout: 10000, // 连接超时 10 秒
  23. },
  24. // 要监听的主题
  25. topic: '/649/YF6660355/property/post'
  26. }
  27. // 创建 MQTT 客户端实例(添加类型注解)
  28. let client: MqttClient | null = null
  29. // 消息回调函数
  30. let messageCallback: MessageCallback | null = null
  31. /**
  32. * 初始化 MQTT 连接
  33. * @param callback 接收消息的回调函数
  34. */
  35. export const initMqtt = (callback: MessageCallback): void => {
  36. // 保存消息回调
  37. messageCallback = callback
  38. // 避免重复连接
  39. if (client && client.connected) {
  40. ElMessage.info('MQTT 已连接')
  41. return
  42. }
  43. try {
  44. // 直接使用静态导入的 mqtt 创建连接(核心修复点)
  45. client = mqtt.connect(MQTT_CONFIG.host, MQTT_CONFIG.options)
  46. // 连接成功
  47. client.on('connect', () => {
  48. ElMessage.success('MQTT 连接成功')
  49. // 订阅指定主题
  50. const subscribeOptions: IClientSubscribeOptions = { qos: 0 }
  51. client?.subscribe(MQTT_CONFIG.topic, subscribeOptions, (err) => {
  52. if (err) {
  53. ElMessage.error(`订阅主题失败:${err.message}`)
  54. } else {
  55. ElMessage.info(`已订阅主题:${MQTT_CONFIG.topic}`)
  56. }
  57. })
  58. })
  59. // 接收消息
  60. client.on('message', (topic: string, payload: Buffer) => {
  61. if (topic === MQTT_CONFIG.topic) {
  62. try {
  63. const messageStr = payload.toString()
  64. const messageObj = JSON.parse(messageStr) as Record<string, any>
  65. // 调用回调函数,将消息传递给组件
  66. messageCallback?.({
  67. topic,
  68. message: messageObj
  69. })
  70. } catch (parseErr) {
  71. ElMessage.error(`消息解析失败:${(parseErr as Error).message}`)
  72. // 解析失败时直接返回字符串
  73. messageCallback?.({
  74. topic,
  75. message: { raw: payload.toString() }
  76. })
  77. }
  78. }
  79. })
  80. // 连接断开
  81. client.on('close', () => {
  82. ElMessage.warning('MQTT 连接已断开')
  83. })
  84. // 连接错误
  85. client.on('error', (err: Error) => {
  86. ElMessage.error(`MQTT 连接错误:${err.message}`)
  87. client?.end()
  88. })
  89. } catch (err) {
  90. const error = err as Error
  91. ElMessage.error(`MQTT 初始化失败:${error.message}`)
  92. }
  93. }
  94. /**
  95. * 断开 MQTT 连接
  96. */
  97. export const disconnectMqtt = (): void => {
  98. if (client) {
  99. client.end()
  100. client = null
  101. ElMessage.info('MQTT 已断开连接')
  102. }
  103. }
  104. /**
  105. * 获取当前 MQTT 连接状态
  106. */
  107. export const getMqttStatus = (): boolean => {
  108. return !!client?.connected
  109. }