8000 fix(sensors): keep a retained MQTT message before acknowledging it by adeelahmad · Pull Request #299 · adeelahmad/lense · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion fastapi_backend/app/domain/mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,11 +286,14 @@ def _serve(self, sock, address):
topic, payload, qos, retain, pid = parse_publish(flags, body)
if not topic or "+" in topic or "#" in topic:
raise ProtocolError("a topic name can't have wildcards")
# kept and passed on before the sender hears it arrived, so a client subscribing after the
# acknowledgement gets it as the retained message
self.publish(topic, payload, retain)
if qos == 1:
session.send(packet(PUBACK, 0, struct.pack("!H", pid)))
elif qos == 2:
session.send(packet(PUBREC, 0, struct.pack("!H", pid)))
self._take(topic, payload, retain, session.login, address)
self._hear(topic, payload, session.login, address)
elif kind == PUBREL:
session.send(packet(PUBCOMP, 0, body[:2]))
elif kind == SUBSCRIBE:
Expand Down Expand Up @@ -329,6 +332,9 @@ def _serve(self, sock, address):

def _take(self, topic, payload, retain, login, address):
self.publish(topic, payload, retain)
self._hear(topic, payload, login, address)

def _hear(self, topic, payload, login, address):
if not topic.startswith("$"):
try:
self.on_message(topic, payload, login, address)
Expand Down
19 changes: 19 additions & 0 deletions fastapi_backend/tests/api/test_sensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,25 @@ def test_broker_is_an_ordinary_local_broker():
b.stop()


def test_a_retained_message_is_kept_before_its_sender_hears_it_arrived():
b = mqtt.Broker("127.0.0.1", 0, lambda *a: {"ok": 1}, lambda *a: None).start()
keep = b.publish

def slow(*a, **kw): # a busy hub: the acknowledgement must still wait for the message to be kept
time.sleep(0.3)
keep(*a, **kw)

b.publish = slow
try:
Device(b.port, "pub", "u", "p").publish("home/kitchen/temp", "21.5", qos=1, retain=True)
sub = Device(b.port, "sub", "u", "p")
assert sub.subscribe("home/#") == [0]
assert sub.receive() == ("home/kitchen/temp", b"21.5", True)
sub.close()
finally:
b.stop()


def test_bridge_client_reads_another_broker():
b = mqtt.Broker("127.0.0.1", 0, lambda *a: {"ok": 1}, lambda *a: None).start()
try:
Expand Down
Loading
0