Skip to content

Registering topic holders and channels

Before opening your connection to the broker, you must define your messaging landscape. This means creating your topic holders and combining them into channels.

Crucial rule: You can only add or remove topic holders and channels while the connection is closed (IsConnectionOpen is false). Trying to modify the topology while actively connected will throw a SyMqttException.

You have three main structural building blocks to work with:

  • SyMqttSenderTopicHolder: Wraps an outbound MQTT topic used for sending messages.
  • SyMqttReceiverTopicHolder: Wraps an inbound MQTT topic used for listening to messages.
  • SyMqttChannel: Pairs a sender and a receiver together to handle synchronous Request-Response workflows.

You can use a fluent API approach to register these components into your SyMqttBox instance:

using SyMqtt;
using SyMqtt.SyMqtt;
using var mqttBox = new SyMqttBox();
// 1. Create independent topic holders
var genericAlertSender = new SyMqttSenderTopicHolder("AlertsOut", "factory/alerts");
var telemetryReceiver = new SyMqttReceiverTopicHolder("TelemetryIn", "factory/telemetry");
// 2. Create a paired channel for Request-Response communication (passing the parent box as the first parameter)
var hvacChannel = new SyMqttChannel(
mqttBox,
channelId: "HvacChannel",
senderTopicHolder: new SyMqttSenderTopicHolder("HvacCmd", "factory/hvac/cmd"),
receiverTopicHolder: new SyMqttReceiverTopicHolder("HvacStatus", "factory/hvac/status")
);
// 3. Register everything into the box before connecting
mqttBox.AddTopic(genericAlertSender)
.AddTopic(telemetryReceiver)
.AddChannel(hvacChannel);

A SyMqttChannel is designed as an open infrastructure component. While its primary job is to orchestrate the internal synchronous Request-Response lifecycle, it exposes its underlying SenderTopicHolder and ReceiverTopicHolder instances as public properties.

This access is useful for implementing cross-cutting concerns like logging, auditing, performance tracking, or real-time UI monitoring. For example, if you need to inspect or log every inbound message arriving on the channel’s response path without interfering with the active synchronous execution, you can attach an independent event handler directly to the receiver:

// Access the underlying receiver topic holder from the channel
var receiverHolder = hvacChannel.ReceiverTopicHolder;
// Attach a dedicated logging handler without disrupting the synchronous flow
receiverHolder.AddReceivedMessageHandler((payload, messageInfo) =>
{
Console.WriteLine($"[Audit Log] Received payload on topic {messageInfo.PublishTopic}: {payload}");
return Task.CompletedTask;
});

Because SyMqttReceiverTopicHolder supports multiple independent subscribers, your telemetry or logging logic runs cleanly in parallel. The SyMqttChannel continues to execute its core functionality related to synchronous communication management normally.

Now that your topology is completely registered inside the box, it is time to configure the network client. Let’s move to the next step to see how to initialize the orchestrator.