получение кол-ва клиентов из mqtt (через topic $SYS/broker/clients/total) nest js

У меня есть бд (mongoDB) разных серверов и мне надо фоном смотреть кол-во клиентов у каждого сервера mqtt (увидите что отделяю их). Для начала server.schema.ts:

//server.schema.ts
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';

@Schema({ timestamps: false, versionKey:false })
export class server {
  @Prop()
  protocol: string; 

  @Prop()
  totalclients: string; 

  @Prop()
  status: boolean; 
  
  @Prop({ type: Object }) 
  data: Record<string, unknown>;

}

export type serverDocument = server & Document;
export const serverSchema = SchemaFactory.createForClass(server);

usepi.service.ts (только то, что касается проблемы):

import { Injectable, Logger } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { server } from './schemas/server.schema';
import * as mqtt from 'mqtt'

@Injectable()
export class UsepiService {

    private readonly logger = new Logger(UsepiService.name);
    constructor(
        @InjectModel(server.name) private readonly serverModel: Model<any>,
    ) {
        this.startPollingForMqttServers()
    }

 async startPollingForMqttServers(): Promise<void> {
        const mqttServers = await this.serverModel.find({ protocol: 'mqtt' });
        mqttServers.forEach(server => {
            const client = mqtt.connect(`mqtt://${server.data.ip}:${server.data.port}`);
            client.on('connect', () => {
                const subscribeToClientsTotal = () => {
                    client.subscribe('$SYS/broker/clients/total', (err) => {
                        if (err) {
                            console.error('Subscription error:', err);
                            return;
                        }
                    });
                };
                client.on('message', async (topic: string, message: Buffer) => {
                    if (topic === '$SYS/broker/clients/total') {
                        const totalClients = parseInt(message.toString());
                        console.log(`Total clients connected of ${server.data.title}: ${totalClients}`);
                        try {
                            const dbServer = await this.serverModel.findById(server.id);
                            if (!dbServer) {
                                console.error('Server not found in the database');
                                return;
                            }
                            if (totalClients !== dbServer.totalclients) {
                                await this.serverModel.findByIdAndUpdate(server.id, { totalclients: totalClients });
                                console.log(`Total clients count updated for server ID ${server.id}: ${totalClients}`);
                            }
                        } catch (error) {
                            console.error('Error updating total clients count:', error);
                        }
                    }
                });
            });
        });
    }      
}      

Я делаю выборку из записей по заголовку protocol -> подписываюсь на топик отвечающий за кол-во подключений. При старте приложения показывает все верно. После отписки какого-то устройства показывает все верно. Стоит только кому то еще подключиться к брокеру, то я начинаю получать бесконечное кол-во сообщений на топик, где с каждым разом кол-во подключений растет. Использую mosquitto.

2023-12-01 23:38:14 Total clients connected of Nameserver: 5
2023-12-01 23:38:20 Total clients connected of Nameserver: 4
2023-12-01 23:38:26 Total clients count updated for server ID 656a17f014a7001438edd19b: 5
2023-12-01 23:38:30 Total clients count updated for server ID 656a17f014a7001438edd19b: 6
2023-12-01 23:38:33 Total clients count updated for server ID 656a17f014a7001438edd19b: 7
2023-12-01 23:38:40 Total clients count updated for server ID 656a17f014a7001438edd19b: 8
..и так до бесконечности

После рестарта приложения все снова сбрасывается в верное кол-во ( 5 ). ситуация повторяется по кругу. голову уже сломал, помогите пожалуйста


Ответы (0 шт):