|
@@ -0,0 +1,196 @@
|
|
|
+<template>
|
|
|
+<div class="mqtt-client">
|
|
|
+ <el-card class="box-card">
|
|
|
+ <template #header>
|
|
|
+ <div class="card-header">
|
|
|
+ <h2>MQTT Client</h2>
|
|
|
+ <el-tag :type="connectionStatus === 'Connected' ? 'success' : 'danger'">
|
|
|
+ {{ connectionStatus }}
|
|
|
+ </el-tag>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <!-- 连接配置 -->
|
|
|
+ <div class="connection-settings">
|
|
|
+ <el-form :model="mqttConfig" label-width="120px">
|
|
|
+ <el-form-item label="Broker URL">
|
|
|
+ <el-input v-model="mqttConfig.url" :disabled="isConnected" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="Topic">
|
|
|
+ <el-input v-model="mqttConfig.topic" :disabled="isConnected" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-button type="primary" @click="toggleConnection" :loading="connecting">
|
|
|
+ {{ isConnected ? 'Disconnect' : 'Connect' }}
|
|
|
+ </el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 消息发送 -->
|
|
|
+ <div class="message-sender" v-if="isConnected">
|
|
|
+ <el-input
|
|
|
+ v-model="messageToSend"
|
|
|
+ placeholder="Enter message to send"
|
|
|
+ :rows="3"
|
|
|
+ type="textarea"
|
|
|
+ />
|
|
|
+ <el-button type="primary" @click="sendMessage" :disabled="!messageToSend" class="send-btn">
|
|
|
+ Send Message
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 消息列表 -->
|
|
|
+ <div class="message-list">
|
|
|
+ <h3>Messages</h3>
|
|
|
+ <el-timeline>
|
|
|
+ <el-timeline-item
|
|
|
+ v-for="(msg, index) in messages"
|
|
|
+ :key="index"
|
|
|
+ :type="msg.type === 'sent' ? 'primary' : 'success'"
|
|
|
+ :timestamp="msg.timestamp"
|
|
|
+ >
|
|
|
+ <el-card class="message-card">
|
|
|
+ <p><strong>{{ msg.type === 'sent' ? 'Sent' : 'Received' }}:</strong></p>
|
|
|
+ <p>{{ msg.content }}</p>
|
|
|
+ </el-card>
|
|
|
+ </el-timeline-item>
|
|
|
+ </el-timeline>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+<script>
|
|
|
+import mqtt from 'mqtt';
|
|
|
+import { MqttClient } from 'mqtt'
|
|
|
+// 状态变量
|
|
|
+var client = MqttClient||null
|
|
|
+export default {
|
|
|
+ components: {},
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ connectionStatus:'',
|
|
|
+ isConnected:false,
|
|
|
+ connecting:false,
|
|
|
+ messages:[{ type: 'sent' , content: '', timestamp: '' }],
|
|
|
+ messageToSend:'',
|
|
|
+ mqttConfig:{
|
|
|
+ url: 'ws://13.229.167.76:1884/mqtt',
|
|
|
+ topic: 'test/topic'
|
|
|
+ },
|
|
|
+ };
|
|
|
+ },
|
|
|
+
|
|
|
+ mounted(){
|
|
|
+
|
|
|
+ },
|
|
|
+ destroyed() {
|
|
|
+ if (client) {
|
|
|
+ client.end()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods:{
|
|
|
+ async toggleConnection(){
|
|
|
+ if (this.isConnected) {
|
|
|
+ // 断开连接
|
|
|
+ client.end()
|
|
|
+ this.isConnected= false
|
|
|
+ this.connectionStatus = 'Disconnected'
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 建立连接
|
|
|
+ this.connecting = true
|
|
|
+ try {
|
|
|
+ client= mqtt.connect(this.mqttConfig.url, {
|
|
|
+ clientId: 'mqttjs_' + Math.random().toString(16).substr(2, 8),
|
|
|
+ keepalive: 60,
|
|
|
+ clean: true,
|
|
|
+ connectTimeout: 4000,
|
|
|
+ reconnectPeriod: 1000
|
|
|
+ })
|
|
|
+
|
|
|
+ client.on('connect', () => {
|
|
|
+ this.isConnected = true
|
|
|
+ this.connectionStatus= 'Connected'
|
|
|
+ this.connecting = false
|
|
|
+
|
|
|
+ // 订阅主题
|
|
|
+ client.subscribe(this.mqttConfig.topic, (err) => {
|
|
|
+ if (err) {
|
|
|
+ console.error('Subscribe error:', err)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ client.on('message', (topic, message) => {
|
|
|
+ this.messages.unshift({
|
|
|
+ type: 'received',
|
|
|
+ content: message.toString(),
|
|
|
+ timestamp: new Date().toLocaleTimeString()
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ client.on('error', (err) => {
|
|
|
+ console.error('MQTT Error:', err)
|
|
|
+ this.connectionStatus= 'Error'
|
|
|
+ this.connecting = false
|
|
|
+ })
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Connection error:', error)
|
|
|
+ this.connectionStatus= 'Error'
|
|
|
+ this.connecting = false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ sendMessage(){
|
|
|
+ if (!client || !this.messageToSend) return
|
|
|
+
|
|
|
+ client.publish(this.mqttConfig.topic, this.messageToSend)
|
|
|
+ this.messages.unshift({
|
|
|
+ type: 'sent',
|
|
|
+ content: this.messageToSend,
|
|
|
+ timestamp: new Date().toLocaleTimeString()
|
|
|
+ })
|
|
|
+ this.messageToSend = ''
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+<style lang="less" scoped>
|
|
|
+.mqtt-client {
|
|
|
+ width: 800px;
|
|
|
+ margin: 20px auto;
|
|
|
+ padding: 0 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.card-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.connection-settings {
|
|
|
+ margin-bottom: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.message-sender {
|
|
|
+ margin-bottom: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.send-btn {
|
|
|
+ margin-top: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+.message-list {
|
|
|
+ margin-top: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.message-card {
|
|
|
+ margin-bottom: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+.el-timeline-item {
|
|
|
+ margin-bottom: 20px;
|
|
|
+}
|
|
|
+</style>
|
|
|
+
|