Android手把手编写儿童手机远程监控App之vue3使用Pinia全局MQTT实例
·
上节完成嘟宝app使用agentweb无法获取摄像头视频流问题。
嘟宝是为监督孩子身边环境而创建的一套应用,它能够实现后台驻留长连接,随时接收嘟妈信令,建立音视频通道点对点通信,而不需要中转 服务器。嘟妈是一套WEB 应用,使用vue3编写,能够兼容app、小程序开发 。目前为止,嘟宝完成的基本功能设计包括
- MQTT 基础通信
- 后台驻留
- SQLite数据存储
- 二维码显示身份识别码
- 开启自启动前台服务
- 任务栏消息发送与点击
嘟宝使用WebRtc与嘟妈建立音视频通信,它的核心需求包含以下部分: - 嘟妈获取嘟宝摄像头、麦克风音视频流
- 获取嘟宝桌面共享内容
- 嘟妈与嘟宝建立音视频通话
嘟妈想要建立与嘟宝交互,登录完成后,扫描嘟宝二维码,完成绑定。这就要求嘟妈调用相机的权限。
嘟妈使用vue3编写,使用agentweb在Android app渲染。在默认情况下,是无法直接获取相机权限的。获取相机权限分两部分完成 - agentweb所在app申请相机权限
- agentweb放行所有权限
嘟宝通过MQTT与嘟宝保持连接,这就要求整个项目保证唯一MQTT实例,实现的方式很多,项目中最常用的是使用Pinia。
安装Pinia
npm install mqtt
引用Pinia
main.ts引用Pinia
import { createApp } from 'vue'
import App from './App.vue'
import router from '@/router/index'
import "vant/lib/index.css";
import { createPinia } from 'pinia'
const app = createApp(App)
const pinia = createPinia()
app.use(pinia)
app.use(router)
app.mount('#app')
使用Pinia创建MQTT实例
- 创建store文件夹,在文件夹中创建mqtt.ts
- 在app.vue创建mqtt数据,建立连接并回调数据
文件结构如下
mqtt.ts源码如下
import { ref } from 'vue';
import { defineStore } from 'pinia';
import mqtt from 'mqtt';
import { getUserData } from '@/api/storge'
import { c } from '@/myconfig'
export const useMQTTStore = defineStore('mqtt', () => {
let client: any = null;
let duma = JSON.parse(getUserData() as string);
let datamsg = ref('');
async function connect() {
if (client != null) {
return;
}
let options = {
keepalive: 60,
clean: true, // true: 清除会话, false: 保留会话
connectTimeout: 4000, // 超时时间
// 认证信息
clientId: 'duma='+duma.dumaId,
username: '',
password: '',
reconnectPeriod: 1000,
will: {
topic: '/law/will/device',
payload: '嘟妈掉线了'+duma.dumaId
}
};
client = mqtt.connect(c.mqtthttpurl, options)
client.on('connect', () => {
console.log('MQTT 已连接')
client.subscribe('/duma/'+duma.dumaId);
})
client.on('reconnect', () => {
console.log('MQTT 正在重连...');
});
client.on('error', (error:any) => {
console.error('MQTT 连接错误:', error);
});;
client.on('message', async (t:any, msg:any) => {
let o:any = {
topic:t,
msg:msg.toString(),
timestamp:Date.now()
}
datamsg.value = JSON.stringify(o);
})
}
async function disconnect() {
client.end();
client = null;
}
async function pushmsg(code: any, d: any) {
let msg:any = {};
msg.dubaoId='8206aa74-69c5-483e-83b5-16616e3030eb';
msg.dumaId = duma.dumaId;
msg.dumaName = "天使嘟妈";
msg.code = code;
msg.data = d;
let s=JSON.stringify(msg)
await client.publish('/dubao/8206aa74-69c5-483e-83b5-16616e3030eb', s)
};
return { datamsg,duma,connect,disconnect,pushmsg}
})
app.vue调用
<template>
<div class="app">
<!-- 路由视图 -->
<div class="main">
<router-view v-slot="{ Component }">
<transition name="fade" mode="out-in">
<component :is="Component" />
</transition>
</router-view>
</div>
<!-- 底部 Tabbar(使用 Vant 4 语法) -->
<van-tabbar route fixed placeholder>
<van-tabbar-item replace to="/home" icon="home-o">首页</van-tabbar-item>
<van-tabbar-item replace to="/code" icon="scan">扫一扫</van-tabbar-item>
<van-tabbar-item replace to="/me" icon="friends-o">我的</van-tabbar-item>
</van-tabbar>
</div>
</template>
<script setup lang="ts">
import { onMounted,onUnmounted } from 'vue'
import { useMQTTStore } from './store/mqtt';
const mqtt = useMQTTStore()
mqtt.$subscribe((mutate, state) => {
console.log(state.datamsg);
});
onMounted(() => {
mqtt.connect();
})
onUnmounted(() => {
mqtt.disconnect();
});
至此完成mqtt实例创建且保持唯一。在任何组件都可以调用mqtt获取订阅消息与发布事件
在me.vue中测试
<template>
<div @click="push" class="container">
wode
</div>
</template>
<script setup lang="ts">
import { useMQTTStore } from '@/store/mqtt';
const mqtt = useMQTTStore()
mqtt.$subscribe((mutate, state) => {
console.log(state.datamsg);
});
function push() {
mqtt.pushmsg('a','hello world')
}
</script>
<style scoped>
.container{
height: 100%;
background-color:aqua;
}
</style>
测试结果如下图:

更多推荐
所有评论(0)