MQTT for Tcl

View Ticket
Login
Ticket Hash: 7f9280a6acce3b90ca171f357ca392a0dd2f0a4e
Title: Simple example (echoing messages) does not receive messages
Status: Closed Type: Code_Defect
Severity: Critical Priority: Immediate
Subsystem: broker Resolution: Not_A_Bug
Last Modified: 2021-11-03 14:31:25
Version Found In: 2.0
User Comments:
anonymous added on 2021-11-03 07:49:30:
My simple example, shown below, does not receive any messages from the sender.

The log from the broker is:

d:\tcl-programs\mqtt-test>tclsh runbroker.tcl
Opening listen socket on port 1883.
New connection from ::1:51058 on port 1883.
Client disconnected
New connection from ::1:51061 on port 1883.
New client connected from ::1 as  (p5, c1, k60)
Sending CONNACK to auto-457037343 (0, 0)
Received SUBSCRIBE from auto-457037343
    # (QoS 2)
auto-457037343 2 #
Sending SUBACK to auto-457037343 (QoS 2)
New connection from ::1:51075 on port 1883.
Client disconnected
Client auto-457037343 disconnected


Procedure:
- start broker (runbroker.tcl)
- start receiver (runclient2.tcl)
- start sender (runclient1.tcl)
  (in this order to make everything is ready)

*** runbroker.tcl ***

# runbroker.tcl --
#     Start a MQTT broker
#
::tcl::tm::path add .
package require mqtt
package require broker

broker log puts
broker create Broker brokerdb

Broker listen

vwait forever


*** runclient1.tcl ***

# runclient1.tcl --
#     Start an MQTT client
#
::tcl::tm::path add .
package require mqtt

mqtt create Send
Send connect Sender

for { set i 0} {$i < 10} {incr i} {
   Send publish ECHO [list "Echo $i"]
   puts $i
   after 1000
}


***runclient2.tcl***

# runclient2.tcl --
#     Start an MQTT client - receive messages
#
::tcl::tm::path add .
package require mqtt

mqtt create Receive
#eceive connect Receiver
Receive connect
Receive subscribe # echoString  ;# Was: ECHO

proc echoString {topic message args} {
    puts "Received: $message ($topic)"
}

vwait forever

schelte added on 2021-11-03 08:56:11:

The problem is that your runclient1 never enters the event loop. It is necessary to do so to allow the connect handshake to complete. A quick and dirty fix is to add the following two lines after the Send connect Sender command:

    after 100 {set connection 1}
    vwait connection

The proper way would be to change your runclient1.tcl to actually wait for confirmation of the connection. For example:

# runclient1.tcl --
#     Start an MQTT client
#
::tcl::tm::path add .
package require mqtt

mqtt create Send
Send subscribe {$SYS/local/connection} connection
Send connect Sender

proc connection {topic data args} {
    if {[dict get $data state] eq "connected"} {
        for { set i 0} {$i < 10} {incr i} {
            Send publish ECHO [list "Echo $i"]
            puts $i
            after 1000
        }
        exit
    }
}

vwait forever


schelte added on 2021-11-03 14:31:25:

Originator confirmed the issue is resolved.