【发布时间】:2021-07-26 03:56:13
【问题描述】:
故事
我正在使用 React Js 和 MQTT 通信在地图中显示大量实时位置数据。你可以把它想象成一个仪表板,显示所有 Uber 司机的实时位置。
我有 7 台设备将其数据广播到 Rabbit MQ 服务器。在 Rabbit MQ 中,我安装了 MQTT 插件,以便我可以使用 React 中的 MQTT 从 Rabbit MQ 服务器检索数据。
来自每个设备的数据在随机时间广播。所以一秒钟不可能没有数据,而某些设备在一秒钟内有很多数据。
假设这是从一台设备广播一次的示例数据:
{ain.1: 0.087, ain.2: 3.234, battery.charging.status: false, battery.current: 0, battery.voltage: 4.066, …}
or:
{ble.beacons: Array(0), channel.id: 10476, device.id: 3, device.name: "Device-3", device.type.id: 579, …}
目标
我想做什么:
- 过滤每个项目(从设备广播):假设我有一个
array来存储每个设备。因为我有 7 个设备,所以我会有一个长度为 7 的array。
- 如果项目具有在
array中找不到的设备ID,则将项目添加到array。 - 如果项目具有在
array中找到的设备 ID,则该项目将替换数组中的旧项目(具有相同的设备 ID)。
- 使用
useState挂钩将data(状态变量)更新为array。
代码
代码如下:
import React, { useEffect, useState } from 'react'
import mqtt from 'mqtt'
export default function RealtimeMarker() {
const [ data, setData ] = useState([])
let array = []
const usingMqtt = () => {
const url = 'ws://blahblahblah/ws'
const client = mqtt.connect(url)
const topicsToSubscribe = 'message/devices/+' // '+' is a wildcard
client.on('connect', () => {
console.log('connected')
client.subscribe(topicsToSubscribe)
})
client.on('message', (topic, message) => {
const itemMessage = JSON.parse(message.toString())
console.log('itemMessage: ', itemMessage)
// ADD NEW ITEM TO EMPTY DATA
if(data.length === 0) {
array.push(itemMessage)
}
// ADD NEW ITEM TO NON-EMPTY DATA
else {
for(let i = 0; i < data.length; i++) {
if(data[i]['device.id'] !== itemMessage['device.id'] && itemMessage['ble.beacons'] === null) {
array.push(itemMessage)
}
}
}
setData(array)
})
}
console.log('data: ', data.length, data)
useEffect(() => {
usingMqtt()
}, [])
return (
<div>
</div>
)
}
主题'message/devices/+'中的+是所有主题的通配符。
依赖:
"mqtt": "^4.2.8",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
环境:
OS: Windows 10 Home
NPM: v6.14.8
Node: v12.9.0
问题:
data 变量只会像这个日志一样永远更新两次。
10:29:46.179 RealtimeMarker.js:65 data: 0 []
10:29:46.326 RealtimeMarker.js:34 connected
10:29:46.610 RealtimeMarker.js:42 itemMessage: {ain.1: 0.087, ain.2: 3.234, battery.charging.status: false, battery.current: 0, battery.voltage: 4.066, …}
10:29:46.611 RealtimeMarker.js:65 data: 1 [{…}]
10:29:48.845 RealtimeMarker.js:42 itemMessage: {ain.1: 0.087, ain.2: 3.046, battery.charging.status: false, battery.current: 0, battery.voltage: 4.01, …}
10:29:48.846 RealtimeMarker.js:65 data: 2 (2) [{…}, {…}]
10:29:49.021 RealtimeMarker.js:42 itemMessage: {ain.1: 0.087, ain.2: 3.043, battery.charging.status: false, battery.current: 0, battery.voltage: 4.01, …}
10:29:49.022 RealtimeMarker.js:42 itemMessage: {ain.1: 0.087, ain.2: 3.041, battery.charging.status: false, battery.current: 0, battery.voltage: 4.01, …}
10:29:49.023 RealtimeMarker.js:42 itemMessage: {ain.1: 0.087, ain.2: 3.048, battery.charging.status: false, battery.current: 0, battery.voltage: 4.01, …}
10:29:49.024 RealtimeMarker.js:42 itemMessage: {ain.1: 0.087, ain.2: 3.033, battery.charging.status: false, battery.current: 0, battery.voltage: 4.01, …}
10:29:51.946 RealtimeMarker.js:42 itemMessage: {ain.1: 0.087, ain.2: 3.234, battery.charging.status: false, battery.current: 0, battery.voltage: 4.071, …}
10:29:53.236 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.854, battery.charging.status: false, battery.current: 0, battery.voltage: 4.006, …}
10:29:53.410 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.854, battery.charging.status: false, battery.current: 0, battery.voltage: 4.007, …}
10:29:53.410 RealtimeMarker.js:42 itemMessage: {ble.beacons: Array(0), channel.id: 10476, device.id: 3, device.name: "Device-3", device.type.id: 579, …}
10:29:53.410 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.6, battery.charging.status: false, battery.current: 0, battery.voltage: 4.03, …}
10:29:53.410 RealtimeMarker.js:42 itemMessage: {ble.beacons: Array(0), channel.id: 10476, device.id: 3, device.name: "Device-3", device.type.id: 579, …}
10:29:53.411 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.6, battery.charging.status: false, battery.current: 0, battery.voltage: 4.03, …}
10:29:56.570 RealtimeMarker.js:42 itemMessage: {ain.1: 0.087, ain.2: 3.234, battery.charging.status: false, battery.current: 0, battery.voltage: 4.066, …}
10:29:58.468 RealtimeMarker.js:42 itemMessage: {ain.1: 0.087, ain.2: 3.048, battery.charging.status: false, battery.current: 0, battery.voltage: 4.01, …}
10:29:58.637 RealtimeMarker.js:42 itemMessage: {ain.1: 0.087, ain.2: 3.041, battery.charging.status: false, battery.current: 0, battery.voltage: 4.01, …}
10:30:01.984 RealtimeMarker.js:42 itemMessage: {ain.1: 0.087, ain.2: 3.234, battery.charging.status: false, battery.current: 0, battery.voltage: 4.067, …}
10:30:03.177 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.854, battery.charging.status: false, battery.current: 0, battery.voltage: 4.01, …}
10:30:03.353 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.854, battery.charging.status: false, battery.current: 0, battery.voltage: 4.008, …}
10:30:03.354 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.608, battery.charging.status: false, battery.current: 0, battery.voltage: 4.03, …}
10:30:03.354 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.512, battery.charging.status: false, battery.current: 0, battery.voltage: 4.03, …}
10:30:03.354 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.512, battery.charging.status: false, battery.current: 0, battery.voltage: 4.03, …}
10:30:06.771 RealtimeMarker.js:42 itemMessage: {ain.1: 0.087, ain.2: 3.234, battery.charging.status: false, battery.current: 0, battery.voltage: 4.066, …}
10:30:11.039 RealtimeMarker.js:42 itemMessage: {ain.1: 0.087, ain.2: 3.05, battery.charging.status: false, battery.current: 0, battery.voltage: 4.01, …}
10:30:11.238 RealtimeMarker.js:42 itemMessage: {ain.1: 0.087, ain.2: 3.037, battery.charging.status: false, battery.current: 0, battery.voltage: 4.01, …}
10:30:11.415 RealtimeMarker.js:42 itemMessage: {ain.1: 0.173, ain.2: 2.735, battery.charging.status: false, battery.current: 0, battery.voltage: 4.004, …}
10:30:11.416 RealtimeMarker.js:42 itemMessage: {ain.1: 0.173, ain.2: 2.735, battery.charging.status: false, battery.current: 0, battery.voltage: 4.004, …}
10:30:11.417 RealtimeMarker.js:42 itemMessage: {ain.1: 0.173, ain.2: 2.746, battery.charging.status: false, battery.current: 0, battery.voltage: 4.004, …}
10:30:11.418 RealtimeMarker.js:42 itemMessage: {ain.1: 0.173, ain.2: 2.785, battery.charging.status: false, battery.current: 0, battery.voltage: 4.004, …}
10:30:11.585 RealtimeMarker.js:42 itemMessage: {ain.1: 0.173, ain.2: 2.754, battery.charging.status: false, battery.current: 0, battery.voltage: 4.004, …}
10:30:11.585 RealtimeMarker.js:42 itemMessage: {ain.1: 0.087, ain.2: 3.234, battery.charging.status: false, battery.current: 0, battery.voltage: 4.066, …}
10:30:11.586 RealtimeMarker.js:42 itemMessage: {ble.beacons: Array(0), channel.id: 10476, device.id: 5, device.name: "Device-5", device.type.id: 579, …}
10:30:12.462 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.854, battery.charging.status: false, battery.current: 0, battery.voltage: 4.008, …}
10:30:12.636 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.854, battery.charging.status: false, battery.current: 0, battery.voltage: 4.01, …}
10:30:12.636 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.512, battery.charging.status: false, battery.current: 0, battery.voltage: 4.03, …}
10:30:12.636 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.558, battery.charging.status: false, battery.current: 0, battery.voltage: 4.03, …}
10:30:12.637 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.549, battery.charging.status: false, battery.current: 0, battery.voltage: 4.03, …}
10:30:16.475 RealtimeMarker.js:42 itemMessage: {ain.1: 0.087, ain.2: 3.234, battery.charging.status: false, battery.current: 0, battery.voltage: 4.066, …}
10:30:21.963 RealtimeMarker.js:42 itemMessage: {ain.1: 0.087, ain.2: 3.234, battery.charging.status: false, battery.current: 0, battery.voltage: 4.067, …}
10:30:22.577 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.854, battery.charging.status: false, battery.current: 0, battery.voltage: 4.006, …}
10:30:22.749 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.854, battery.charging.status: false, battery.current: 0, battery.voltage: 4.01, …}
10:30:22.750 RealtimeMarker.js:42 itemMessage: {ble.beacons: Array(0), channel.id: 10476, device.id: 3, device.name: "Device-3", device.type.id: 579, …}
10:30:22.751 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.595, battery.charging.status: false, battery.current: 0, battery.voltage: 4.03, …}
10:30:22.752 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.562, battery.charging.status: false, battery.current: 0, battery.voltage: 4.03, …}
10:30:26.452 RealtimeMarker.js:42 itemMessage: {ain.1: 0.087, ain.2: 3.234, battery.charging.status: false, battery.current: 0, battery.voltage: 4.066, …}
10:30:31.486 RealtimeMarker.js:42 itemMessage: {ain.1: 0.087, ain.2: 3.234, battery.charging.status: false, battery.current: 0, battery.voltage: 4.067, …}
10:30:32.226 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.854, battery.charging.status: false, battery.current: 0, battery.voltage: 4.01, …}
10:30:32.401 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.854, battery.charging.status: false, battery.current: 0, battery.voltage: 4.006, …}
10:30:32.401 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.571, battery.charging.status: false, battery.current: 0, battery.voltage: 4.03, …}
10:30:32.402 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.567, battery.charging.status: false, battery.current: 0, battery.voltage: 4.03, …}
10:30:32.402 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.578, battery.charging.status: false, battery.current: 0, battery.voltage: 4.03, …}
10:30:34.401 RealtimeMarker.js:42 itemMessage: {ain.1: 0.087, ain.2: 3.039, battery.charging.status: false, battery.current: 0, battery.voltage: 4.01, …}
10:30:34.568 RealtimeMarker.js:42 itemMessage: {ain.1: 0.087, ain.2: 3.039, battery.charging.status: false, battery.current: 0, battery.voltage: 4.01, …}
10:30:36.795 RealtimeMarker.js:42 itemMessage: {ain.1: 0.087, ain.2: 3.234, battery.charging.status: false, battery.current: 0, battery.voltage: 4.066, …}
10:30:40.088 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.854, battery.charging.status: false, battery.current: 0, battery.voltage: 4.011, …}
10:30:40.248 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.553, battery.charging.status: false, battery.current: 0, battery.voltage: 4.03, …}
10:30:40.248 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.556, battery.charging.status: false, battery.current: 0, battery.voltage: 4.03, …}
10:30:40.248 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.553, battery.charging.status: false, battery.current: 0, battery.voltage: 4.03, …}
10:30:40.248 RealtimeMarker.js:42 itemMessage: {ain.1: 0.043, ain.2: 2.553, battery.charging.status: false, battery.current: 0, battery.voltage: 4.03, …}
10:30:41.425 RealtimeMarker.js:42 itemMessage: {ain.1: 0.087, ain.2: 3.234, battery.charging.status: false, battery.current: 0, battery.voltage: 4.066, …}
10:30:41.599 RealtimeMarker.js:42 itemMessage: {ble.beacons: Array(0), channel.id: 10476, device.id: 5, device.name: "Device-5", device.type.id: 579, …}
10:30:44.862 RealtimeMarker.js:42 itemMessage: {ain.1: 0.173, ain.2: 2.735, battery.charging.status: false, battery.current: 0, battery.voltage: 4.004, …}
10:30:45.023 RealtimeMarker.js:42 itemMessage: {ain.1: 0.173, ain.2: 2.735, battery.charging.status: false, battery.current: 0, battery.voltage: 4.004, …}
10:30:45.024 RealtimeMarker.js:42 itemMessage: {ain.1: 0.173, ain.2: 2.746, battery.charging.status: false, battery.current: 0, battery.voltage: 4.004, …}
10:30:45.024 RealtimeMarker.js:42 itemMessage: {ain.1: 0.173, ain.2: 2.785, battery.charging.status: false, battery.current: 0, battery.voltage: 4.004, …}
10:30:45.024 RealtimeMarker.js:42 itemMessage: {ain.1: 0.173, ain.2: 2.754, battery.charging.status: false, battery.current: 0, battery.voltage: 4.004, …}
10:30:46.328 RealtimeMarker.js:42 itemMessage: {ain.1: 0.087, ain.2: 3.234, battery.charging.status: false, battery.current: 0, battery.voltage: 4.066, …}
10:30:47.899 RealtimeMarker.js:34 connected
您可以看到data 只更新了两次,尽管所有 7 台设备的数据都传输到了 React 应用程序。
还有一件事不清楚。如您所见,在10:29:46.611,数据的长度为1。如果我打开data,data 的长度大于1,如下所示:
0: {ain.1: 0.173, ain.2: 2.974, battery.charging.status: false, battery.current: 0, battery.voltage: 4.004, …}
1: {ain.1: 0.173, ain.2: 2.968, battery.charging.status: false, battery.current: 0, battery.voltage: 4.004, …}
2: {ain.1: 0.173, ain.2: 2.972, battery.charging.status: false, battery.current: 0, battery.voltage: 4.004, …}
3: {ain.1: 0.173, ain.2: 2.97, battery.charging.status: false, battery.current: 0, battery.voltage: 4.004, …}
4: {ain.1: 0.173, ain.2: 2.955, battery.charging.status: false, battery.current: 0, battery.voltage: 4.004, …}
5: {ain.1: 0.087, ain.2: 3.033, battery.charging.status: false, battery.current: 0, battery.voltage: 4.01, …}
6: {ain.1: 0.043, ain.2: 2.894, battery.charging.status: false, battery.current: 0, battery.voltage: 4.01, …}
7: {ain.1: 0.043, ain.2: 2.887, battery.charging.status: false, battery.current: 0, battery.voltage: 4.008, …}
8: {ain.1: 0.043, ain.2: 2.593, battery.charging.status: false, battery.current: 0, battery.voltage: 4.03, …}
9: {ain.1: 0.043, ain.2: 2.589, battery.charging.status: false, battery.current: 0, battery.voltage: 4.03, …}
问题
- 怎么会这样?我的代码有什么问题?
- 如何解决或达到目标?
注意
如果这个案例不是很清楚,请在评论区告诉我。我会尽快更新问题。
【问题讨论】:
标签: javascript reactjs react-hooks mqtt