Tauri 2.0 使用 MQTT 订阅和发送消息

500 阅读2分钟

首先明确一点,在浏览器环境是不能直接直接使用 MQTT 协议的,需要先将 MQTT 转换成 WebSocket 协议。所以依照传统思路想要在 Tauri 中使用 MQTT 也必须将其转为 WebSocket。

但在 Tauri 中有没有特殊办法直接使用 mqtt:// 呢?

答案是有的,那就是用 rust

第一步:安装依赖包

首先进入 /src-tauri 目录,执行以下命令:

cargo add tauri-plugin-mqtt

然后回到根目录,执行以下命令:

npm i @kuyoonjo/tauri-plugin-mqtt

接着将 tauri-plugin-mqtt 添加到 /src-tauri/src/lib.rs

tauri::Builder::default()
    .plugin(tauri_plugin_mqtt::init())
    ...

最后将 mqtt:default 添加到 /src-tauri/capabilities/default.json 中的 permissions 里,否则是不能使用 MQTT 的:

{
  "permissions": [
    ...
    "mqtt:default"
  ]
}

到这里所需要的依赖包和相关配置都搞定了。

第二步:连接和订阅

所需的依赖包就绪以后就可以在任意页面中订阅消息了,这里以 Vue 为例:

import { connect, subscribe } from "@kuyoonjo/tauri-plugin-mqtt";

// MQTT 连接 ID
const mqttId = 'my-tauri-app-mqtt' // 每一个连接到 MQTT 服务器的 ID 都要确保是唯一的

// MQTT 服务器信息
const mqttServer = '192.168.20.200:1883'
const mqttUsername = 'username'
const mqttPassword = 'password'

// 订阅主题
const mqttTopic = 'mqtt-topic' // 用于接收消息,需要和后端约定好

// 服务质量
const mqttQos = 0 // 0 最多一次, 1 至少一次, 2 恰好一次

onMounted(async () => {
  try {
    // 连接 MQTT 服务器
    await connect(mqttId, `mqtt://${mqttUsername}:${mqttPassword}@${mqttServer}`)
    console.log('MQTT 连接成功')

    // 订阅主题
    await subscribe(mqttId, mqttTopic, mqttQos)
    console.log(`已订阅主题: ${mqttTopic}`)

    // 监听消息
    listen(x => {
      const message = x.payload.event.message
      if (message) {
        const payload = message.payload
        const formattedMessage = String.fromCharCode(...payload)
        console.log(`收到消息,主题: ${message.topic}, 内容: ${formattedMessage}`)
      }
    })
  } catch (error) {
    console.error('MQTT 连接错误:', error)
  }
})

第三步:发送消息

import { publish } from "@kuyoonjo/tauri-plugin-mqtt";

// 发送消息的主题
const publishTopic = 'publish-topic'

// 要发送的消息
const greetMsg = ref('')

// 发送消息
const sendMsg = async () => {
  await publish(mqttId, publishTopic, mqttQos, false, greetMsg.value)
  console.log('已发送')
}

第四步:取消订阅并断开连接

import { unsubscribe, disconnect } from '@kuyoonjo/tauri-plugin-mqtt'

// 取消订阅并断开连接
const disconnectMqtt = async () => {
  await unsubscribe(mqttId, mqttTopic)
  console.log('已取消订阅')
  await disconnect(mqttId)
  console.log('已断开连接')
}

完整代码

import { connect, subscribe, listen, publish, unsubscribe, disconnect } from '@kuyoonjo/tauri-plugin-mqtt'

// MQTT 连接 ID
const mqttId = 'my-tauri-app-mqtt'

// MQTT 服务器信息
const mqttServer = '192.168.20.200:1883'
const mqttUsername = 'username'
const mqttPassword = 'password'

// MQTT 订阅主题
const mqttTopic = 'mqtt-topic' // 用于接收消息,需要和后端约定好

// 服务质量
const mqttQos = 0 // 0 最多一次, 1 至少一次, 2 恰好一次

onMounted(async () => {
  try {
    // 连接 MQTT 服务器
    await connect(mqttId, `mqtt://${mqttUsername}:${mqttPassword}@${mqttServer}`)
    console.log('MQTT 连接成功')

    // 订阅主题
    await subscribe(mqttId, mqttTopic, mqttQos)
    console.log(`已订阅主题: ${mqttTopic}`)

    // 监听消息
    listen(x => {
      const message = x.payload.event.message
      if (message) {
        const payload = message.payload
        const formattedMessage = String.fromCharCode(...payload)
        console.log(`收到消息,主题: ${message.topic}, 内容: ${formattedMessage}`)
      }
    })
  } catch (error) {
    console.error('MQTT 连接错误:', error)
  }
})

// 发送消息的主题
const publishTopic = 'publish-topic'

// 要发送的消息
const greetMsg = ref('')

// 发送消息
const sendMsg = async () => {
  await publish(mqttId, publishTopic, mqttQos, false, greetMsg.value)
  console.log('已发送')
}

// 取消订阅并断开连接
const disconnectMqtt = async () => {
  await unsubscribe(mqttId, mqttTopic)
  console.log('已取消订阅')
  await disconnect(mqttId)
  console.log('已断开连接')
}