Managing MQTT Broker Clients - Part 3

Managing MQTT Broker Clients - Part 3

Using the TCL Dictionary Command

Multiple Brokers

Connecting to more than one broker requires a feature to manage and switch between them at any given time. For our application, the user assigns a unique name for each connection.

The connection name serves as the primary "key" for storing and retrieving settings. Selecting a broker is easily accommodated using a combo box populated with the various connection names.

image.png

We will use a nested dictionary to store and retrieve the connection name and associated broker settings.

Dictionary - Named Connections and Settings

The nested dictionary is structured as follows:

Broker Clients {
    ConnectionName_1 Settings_1 {
                          > Setting_1 Value_1
                          > ... 
                          > Setting_n Value_n }
    }
    ...
    ConnectionName_n Settings_n {
                          > Setting_1 Value_1
                          > ... 
                          > Setting_n Value_n }
    }
}

The application will always maintain the settings for a "Default" connection. The total number of named connections is maintained using the "ConnectionID" setting in the "Default" settings.

In Part 4 of this series, we discuss a method to store and retrieve all connection settings from a "Connections.cfg" file.

set ::ConnectionNames {}

set ConnectionID 0
set ConnectionName "Default"
puts "Connection Name:  $ConnectionName - ID:  $ConnectionID"
set Settings [dict create connectionID $ConnectionID \
                                connected false \
                                instance "" \
                                keepalive 60 \
                                UserName "Redge" \
                                Password "" \
                                protocol 4 \
                                host "localhost" \
                                port 1883\
                                topics {} \
                                crlf "\n" ]
set BrokerClients [dict create $ConnectionName $Settings]

incr ConnectionID
# Update Default to track count of connectionIDs
dict set BrokerClients Default connectionID $ConnectionID

# Append another ConnectionName to the dictionary
set ConnectionName "Current"
puts "Connection Name:  $ConnectionName - ID:  $ConnectionID"
set Settings [dict create connectionID $ConnectionID \
                                connected false \
                                clientInstance "" \
                                keepalive 60 \
                                UserName "Redge" \
                                Password "" \
                                protocol 4 \
                                host "localhost" \
                                port 1883\
                                topics {} \
                                crlf "\n" ]
dict append BrokerClients $ConnectionName $Settings

We can now use the dict set and dict get commands to change and retrieve values from the dictionary. The following code retrieves the value for the "keepalive" setting:

dict get $BrokerClients Default keepalive

Getting the Dictionary Keys and Values

Referring to the two procedures below, the first procedure, "getConnectionNames," returns a list of all connection names and the second procedure, "getConnectionSettings," returns a dictionary of settings for a given connection name.

# Get/show current broker client connection names
proc getConnectionNames {} {
    puts "Execute getConnectionNames"
    global BrokerClients ConnectionNames

    set ::ConnectionNames [ dict keys $::BrokerClients ]
    set returnList $::ConnectionNames

    puts "Global ::ConnectionNames =\n$::ConnectionNames"

    # The following is for debugging/informational purposes only
    foreach ConnectionName $returnList {
        puts "Connection Name:  $ConnectionName"
    }
    puts "Exiting getConnectionNames"
    return $returnList
}

# Get/show current broker connection settings
proc getConnectionSettings { ConnectionName } {
    puts "Execute getConnectionSettings for:  $ConnectionName"
    global BrokerClients ConnectionNames

    # Does the connection name exist?
    if { [dict exists $::BrokerClients $ConnectionName] } {
        puts "Connection Name Exists:  $ConnectionName"
        puts "Setting\t\tValue"
        set returnList [ dict get $::BrokerClients $ConnectionName ]

        # The following is for debugging/informational purposes only
        dict for { setting value } $returnList {
            puts "$setting\t\t$value"
        }
    } else {
        errors "Error - Connection Name Not Found:  $ConnectionName"
    }
    puts "Exiting getConnectionSettings"
    return $returnList
}

We can retrieve the connection names and settings as shown in the following code snippet:

set ListConnectionNames [ getConnectionNames ]

puts "Executing:  foreach connection $connectionSettings "
foreach connectionName $ListConnectionNames {
    getConnectionSettings $connectionName
}

Saving Connections

We can save the contents of the dictionary directly to a file and retrieve them at any time. This is the topic of our next post, "Use a file to Save and Retrieve a Tcl Dictionary."

Did you find this article valuable?

Support Redge Shepherd by becoming a sponsor. Any amount is appreciated!