从 MQTT 接收到信号 R 的数据出现问题

问题描述 投票:0回答:1

这是与 javescript 和 signalr 相关的代码,数据是从 MQTT 接收的,并且部分工作 -

同一网络的数据会被旧数据清除并反映在新数据中,但是当数据发送到其他网络时,数据会消失或被清除,这就是问题

// Object to store unique camera IDs for each network
let uniqueCameraIds = {};

// Mapping for camera IDs to image paths
let cameraImagePaths = {};

// Object to store network-specific data
let networkData = {};

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/hub/status")
    .build();

connection.start()
    .then(() => {
        console.log("SignalR connected");

        connection.on("ReceiveMessage", (message, imgPaths) => {
            console.log("Received data from SignalR:", message);

            try {
                let data = typeof message === 'string' ? JSON.parse(message) : message;
                let msgTypes = data.msg_content.split(":");

                if (msgTypes[0] === 'm') {
                    handleObjectMessage(data, imgPaths);
                } else if (msgTypes[0] === 'h') {
                    handleHeartbeatMessage(data);
                }
            } catch (error) {
                console.error("Error parsing JSON or extracting values:", error);
            }
        });
    })
    .catch((err) => {
        console.error("Error starting SignalR connection:", err.toString());
    });

function handleObjectMessage(data, imgPaths) {
    let msgContent = data.msg_content.slice(2);
    let zoneDataArray = msgContent.split('|');

    // Extract and log the address
    let receivedAddress = `${data.network_add}.${data.node_add}`;
    console.log("Received address:", receivedAddress);

    // Check if the networkData object exists for the received network
    if (!networkData[receivedAddress]) {
        console.log(`Initializing data for network: ${receivedAddress}`);
        networkData[receivedAddress] = {
            uniqueCameraIds: [],
            cameraImagePaths: {},
            currentNetworkAddress: receivedAddress, // Store the current network address
            isFirstTime: true // isFirstTime is set to true during initialization
        };
    }

    // Clear old data if it's not the first time and the received network matches the current network
    if (!networkData[receivedAddress].isFirstTime && receivedAddress === networkData[receivedAddress].currentNetworkAddress) {
        console.log(`Clearing old data for network: ${receivedAddress}`);
        console.log("Current network address:", networkData[receivedAddress].currentNetworkAddress);
        console.log("isFirstTime:", networkData[receivedAddress].isFirstTime);

        // Clear data only for the current network
        clearDataForNetwork(receivedAddress);
        console.log("After clearing old data. Current network address:", networkData[receivedAddress].currentNetworkAddress);
    }

    // Retain data for cameras in the same network
    zoneDataArray.forEach(zoneData => {
        let cameraId = zoneData.split(',')[0];

        // Check if the cameraId is already in the uniqueCameraIds array
        if (!networkData[receivedAddress].uniqueCameraIds.includes(cameraId)) {
            networkData[receivedAddress].uniqueCameraIds.push(cameraId);
        }
    });

    imgPaths.forEach(imgPath => {
        Object.keys(imgPath).forEach(cameraId => {
            networkData[receivedAddress].cameraImagePaths[cameraId] = imgPath[cameraId];
        });
    });

    // Update the current network address
    networkData[receivedAddress].currentNetworkAddress = receivedAddress;
    networkData[receivedAddress].isFirstTime = false;

    // Update the camera table only if the corresponding HTML element exists
    let dashboardElement = document.getElementById(`dashboard${receivedAddress}`);
    if (dashboardElement !== null) {
        console.log(`Received address ${receivedAddress} exists in the HTML model.`);
        updateCameraTable(zoneDataArray, data, receivedAddress);
    } else {
        console.warn(`Received address ${receivedAddress} and id do not match Error.`);
    }
}

function clearDataForNetwork(networkAddress) {
    networkData[networkAddress].uniqueCameraIds.forEach((cameraId) => {
        clearTableForCamera(networkAddress, cameraId);
    });

    // Reset the networkData object for the current network
    networkData[networkAddress].uniqueCameraIds = [];
    networkData[networkAddress].cameraImagePaths = {};
}

function updateCameraTable(zoneDataArray, data, receivedAddress) {
    zoneDataArray.forEach((zoneData) => {
        let values = zoneData.split(',');

        let cameraId = values[0];
        let zoneId = values[1];
        let peopleCount = values[2];
        let carCount = values[3];
        let truckCount = values[4];
        let motorcycleCount = values[5];
        let miscCount = values[6];

        console.log("Extracted values:", receivedAddress, data.msg_id, cameraId, zoneId, peopleCount, carCount, truckCount, motorcycleCount, miscCount);

        if (cameraId === null || cameraId === undefined) {
            console.error("Camera ID is null or undefined. Handle this condition as needed.");
            return;
        }

        let formattedZoneId = `Zone${zoneId.replace('|', '_')}`;

        let tableCell = $(`#tableZone${cameraId} [data-zone="${formattedZoneId}"]`);

        if (tableCell.find('.people').text() === '-') {
            tableCell.find('.people').text(` ${peopleCount}`);
            tableCell.find('.car').text(` ${carCount}`);
            tableCell.find('.truck').text(` ${truckCount}`);
            tableCell.find('.bike').text(` ${motorcycleCount}`);
            tableCell.find('.misc').text(` ${miscCount}`);
        }

        if (networkData[receivedAddress].cameraImagePaths[cameraId]) {
            $(`#ImageCard${cameraId} .image-card`).attr('src', networkData[receivedAddress].cameraImagePaths[cameraId]);
            console.log(`Image path for camera ${cameraId}: ${networkData[receivedAddress].cameraImagePaths[cameraId]}`);
        }
    });
}

function handleHeartbeatMessage(data) {
    // TODO: get the element of ONLINE-OFFLINE and change the text when heartbeat is received
    let spanElement = document.getElementById(`d-${data.network_add}.${data.node_add}`);
    console.log("found span element");
}

function clearTableForCamera(networkAddress, cameraId) {
    $(`#tableZone${cameraId} [data-zone] td:not(:first-child)`).text('-');
}

同一网络的数据会被旧数据清除并反映在新数据中,但是当其他网络的数据消失或被清除时,这就是问题

javascript signalr asp.net-core-signalr
1个回答
0
投票

我对网络数据处理逻辑的调整确保只有当同一网络地址收到新数据时才会清除该网络的旧数据。这样做的目的是为了避免来自不同网络的数据相互干扰。

这是示例代码

// Object to store unique camera IDs for each network
let uniqueCameraIds = {};

// Mapping for camera IDs to image paths
let cameraImagePaths = {};

// Object to store network-specific data
let networkData = {};

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/hub/status")
    .build();

connection.start()
    .then(() => {
        console.log("SignalR connected");

        connection.on("ReceiveMessage", (message, imgPaths) => {
            console.log("Received data from SignalR:", message);

            try {
                let data = typeof message === 'string' ? JSON.parse(message) : message;
                let msgTypes = data.msg_content.split(":");

                if (msgTypes[0] === 'm') {
                    handleObjectMessage(data, imgPaths);
                } else if (msgTypes[0] === 'h') {
                    handleHeartbeatMessage(data);
                }
            } catch (error) {
                console.error("Error parsing JSON or extracting values:", error);
            }
        });
    })
    .catch((err) => {
        console.error("Error starting SignalR connection:", err.toString());
    });

function handleObjectMessage(data, imgPaths) {
    let msgContent = data.msg_content.slice(2);
    let zoneDataArray = msgContent.split('|');
    // Extract and log the address
    let receivedAddress = `${data.network_add}.${data.node_add}`;
    console.log("Received address:", receivedAddress);

    // Check if the networkData object exists for the received network
    if (!networkData[receivedAddress]) {
        console.log(`Initializing data for network: ${receivedAddress}`);
        networkData[receivedAddress] = {
            uniqueCameraIds: [],
            cameraImagePaths: {},
            currentNetworkAddress: receivedAddress, // Store the current network address
            isFirstTime: true // isFirstTime is set to true during initialization
        };
    } else {
        if (receivedAddress === networkData[receivedAddress].currentNetworkAddress) {
            clearDataForNetwork(receivedAddress);
        }
    }

    // Update the current network address
    networkData[receivedAddress].currentNetworkAddress = receivedAddress;
    updateNetworkData(receivedAddress, zoneDataArray, imgPaths);

    let dashboardElement = document.getElementById(`dashboard${receivedAddress}`);
    if (dashboardElement !== null) {
        updateCameraTable(zoneDataArray, data, receivedAddress);
    } else {
        console.warn(`Dashboard element for address ${receivedAddress} not found.`);
    }
}

function clearDataForNetwork(networkAddress) {
    if (networkData[networkAddress]) {
        networkData[networkAddress].uniqueCameraIds.forEach((cameraId) => {
            clearTableForCamera(networkAddress, cameraId);
        });
        // Reset the networkData object for the current network
        networkData[networkAddress].uniqueCameraIds = [];
        networkData[networkAddress].cameraImagePaths = {};
    }
}


function updateNetworkData(networkAddress, zoneDataArray, imgPaths) {
    zoneDataArray.forEach(zoneData => {
        let cameraId = zoneData.split(',')[0];
        // Check if the cameraId is already in the uniqueCameraIds array
        if (!networkData[networkAddress].uniqueCameraIds.includes(cameraId)) {
            networkData[networkAddress].uniqueCameraIds.push(cameraId);
        }
    });

    imgPaths.forEach(imgPath => {
        Object.keys(imgPath).forEach(cameraId => {
            networkData[networkAddress].cameraImagePaths[cameraId] = imgPath[cameraId];
        });
    });

    networkData[networkAddress].isFirstTime = false;
}

function updateCameraTable(zoneDataArray, data, receivedAddress) {
     zoneDataArray.forEach((zoneData) => {
        let values = zoneData.split(',');

        let cameraId = values[0];
        let zoneId = values[1];
        let peopleCount = values[2];
        let carCount = values[3];
        let truckCount = values[4];
        let motorcycleCount = values[5];
        let miscCount = values[6];

        console.log("Extracted values:", receivedAddress, data.msg_id, cameraId, zoneId, peopleCount, carCount, truckCount, motorcycleCount, miscCount);

        if (cameraId === null || cameraId === undefined) {
            console.error("Camera ID is null or undefined. Handle this condition as needed.");
            return;
        }

        let formattedZoneId = `Zone${zoneId.replace('|', '_')}`;

        let tableCell = $(`#tableZone${cameraId} [data-zone="${formattedZoneId}"]`);

        if (tableCell.find('.people').text() === '-') {
            tableCell.find('.people').text(` ${peopleCount}`);
            tableCell.find('.car').text(` ${carCount}`);
            tableCell.find('.truck').text(` ${truckCount}`);
            tableCell.find('.bike').text(` ${motorcycleCount}`);
            tableCell.find('.misc').text(` ${miscCount}`);
        }

        if (networkData[receivedAddress].cameraImagePaths[cameraId]) {
            $(`#ImageCard${cameraId} .image-card`).attr('src', networkData[receivedAddress].cameraImagePaths[cameraId]);
            console.log(`Image path for camera ${cameraId}: ${networkData[receivedAddress].cameraImagePaths[cameraId]}`);
        }
    });
}

function handleHeartbeatMessage(data) {
    // TODO: get the element of ONLINE-OFFLINE and change the text when heartbeat is received
    let spanElement = document.getElementById(`d-${data.network_add}.${data.node_add}`);
    console.log("found span element");
}

function clearTableForCamera(networkAddress, cameraId) {
    $(`#tableZone${cameraId} [data-zone] td:not(:first-child)`).text('-');
}
© www.soinside.com 2019 - 2024. All rights reserved.