moscajs / aedes

Barebone MQTT broker that can run on any stream server, the node way
MIT License
1.75k stars 228 forks source link

[question] Zero length packet when connect and subscribe #960

Closed Viiprogrammer closed 3 weeks ago

Viiprogrammer commented 3 weeks ago

My server code:

const Aedes = require('aedes')
const { createServer } = require('net')
const MONGO_URL = 'mongodb://localhost:27017/'

const mq = require('mqemitter-mongodb')({
  url: MONGO_URL
})

const persistence = require('aedes-persistence-mongodb')({
  url: MONGO_URL
})

const port = 1883

const aedes = Aedes({
  id: 'main',
  mq,
  persistence
})

const server = createServer(aedes.handle)

let counter = 0

server.listen(port, '0.0.0.0', function () {
  console.log('Aedes listening on port:', port)
  setInterval(() => aedes.publish({
    topic: 'test', payload: JSON.stringify({ a: 1, b: ++counter }),
    retain: true,
    qos: 2
  }), 10000)
})

server.on('error', function (err) {
  console.log('Server error', err)
})

aedes.on('subscribe', function (subscriptions, client) {
  console.log('MQTT client \x1b[32m' + (client ? client.id : client) +
          '\x1b[0m subscribed to topics: ' + subscriptions.map(s => s.topic).join('\n'), 'from broker', aedes.id)
})

aedes.on('unsubscribe', function (subscriptions, client) {
  console.log('MQTT client \x1b[32m' + (client ? client.id : client) +
          '\x1b[0m unsubscribed to topics: ' + subscriptions.join('\n'), 'from broker', aedes.id)
})

// fired when a client connects
aedes.on('client', function (client) {
  console.log('Client Connected: \x1b[33m' + (client ? client.id : client) + '\x1b[0m', 'to broker', aedes.id)
})

// fired when a client disconnects
aedes.on('clientDisconnect', function (client) {
  console.log('Client Disconnected: \x1b[31m' + (client ? client.id : client) + '\x1b[0m', 'to broker', aedes.id)
})

// fired when a message is published
aedes.on('publish', async function (packet, client) {
  console.log('Client \x1b[31m' + (client ? client.id : 'BROKER_' + aedes.id) + '\x1b[0m has published', packet.payload.toString(), 'on', packet.topic, 'to broker', aedes.id)
})

My client code:

const mqtt = require("mqtt");
const client = mqtt.connect("mqtt://localhost:1883", {
  clientId: 'anonbot',
  clean: false,
  protocolVersion: 3
});

client.on("connect", () => {
  client.on("message", (topic, message, packet) => {
    console.log('message', topic, message.toString(), packet);
  });

  client.subscribe('test', { qos: 2 }, (err, data) => {
    if (!err) {
      //console.log('test', err, data)
      //client.publish("presence", "Hello mqtt");
    }
  });
});

When I start the client and connect + subscribe to the test topic (having previously created a session with clear: false), every time I connect, I receive 1 extra packet with an empty buffer.

message test  Packet {
  cmd: 'publish',
  retain: true,
  qos: 2,
  dup: false,
  length: 8,
  topic: 'test',
  payload: <Buffer >,
  messageId: 21631
}

I don't know why that happens. It doesn't seem to be "Last Will and Testament" package, because if I configure will in the client, I receive the Last Will and Testament along with this empty packet.

Also, same packet (empty) I receive with application MQTTX image

robertsLando commented 3 weeks ago

@Viiprogrammer That's a retained packet, you should delete it from your broker

Viiprogrammer commented 3 weeks ago

@Viiprogrammer That's a retained packet, you should delete it from your broker

Yes, but I didn't created empty packets with retain. In my logs / examples I use clean database, cold start with 1 publish (not empty) + disconnect. After, next connections i still receive that empty packet every connection

robertsLando commented 3 weeks ago

@Viiprogrammer Try to change db and you will see you will not receive that message anymore... The message is stored on mongodb retained

Viiprogrammer commented 3 weeks ago

@Viiprogrammer Try to change db and you will see you will not receive that message anymore... The message is stored on mongodb retained

Yes, when I clean database not receive, but I didn't understand where from that message.

Every time when I clean DB and connect - zero packet will not receive.

But if I publish anything from server, after disconnect and connect, I receive that package (I don't ever send it)

https://github.com/moscajs/aedes/assets/17622604/70301d75-b7c3-4b63-abdf-1f1ba597e821

Or you suggest replace MongoDB adapters with other (Redis and etc.), MongoDB is not recommended?

robertsLando commented 3 weeks ago

@Viiprogrammer checkl the aedes code you wrote above:

server.listen(port, '0.0.0.0', function () {
  console.log('Aedes listening on port:', port)
  setInterval(() => aedes.publish({
    topic: 'test', payload: JSON.stringify({ a: 1, b: ++counter }),
    retain: true,
    qos: 2
  }), 10000)
})

This interval publishes that message, remove that and you will not see it anymore.