MQTTnet
MQTTnet copied to clipboard
ClientId of Server not set when publishing messages
Describe the bug
I set the ClientId of the server in the MqttServerOptionsBuilder but when I publish a message from the server, the ClientId is null. On the receiving client side this results in the ClientId being set to the ClientId of the receiving client.
Which project is your bug related to?
- Client
- Server
To Reproduce
Steps to reproduce the behavior:
- Using this version of MQTTnet '3.0.12'.
- Run this code => see below.
- With these arguments '....'.
- See error: ClientId on client Receiver is always "Receiver" while the real sender is the server with ClientId "Sender" but is always null
Expected behavior
I would expect the ClientId of the server to be set correctly and see the ClientId on the receiver being set to the ClientId of the server (or at least null but not the receivers own ClientId).
Additional context / logging
Receiver:
Received message from Receiver on topic TestTopic with message Test message 156
Received message from Receiver on topic TestTopic with message Test message 157
Received message from Receiver on topic TestTopic with message Test message 158
Received message from Receiver on topic TestTopic with message Test message 159
Received message from Receiver on topic TestTopic with message Test message 160
Received message from Receiver on topic TestTopic with message Test message 161
Received message from Receiver on topic TestTopic with message Test message 162
Received message from Receiver on topic TestTopic with message Test message 163
Received message from Receiver on topic TestTopic with message Test message 164
Server (via ApplicationMessageReceivedHandler):
[11:31:52 DBG] Received message from null on topic TestTopic with message Test message 167
[11:31:57 DBG] Received message from null on topic TestTopic with message Test message 168
[11:32:02 DBG] Received message from null on topic TestTopic with message Test message 169
[11:32:07 DBG] Received message from null on topic TestTopic with message Test message 170
[11:32:12 DBG] Received message from null on topic TestTopic with message Test message 171
[11:32:17 DBG] Received message from null on topic TestTopic with message Test message 172
[11:32:22 DBG] Received message from null on topic TestTopic with message Test message 173
Code example
Server:
private static IMqttServer _communicator;
public override Task StartAsync(CancellationToken cancellationToken)
{
_communicator = new MqttFactory().CreateMqttServer();
var options = new MqttServerOptionsBuilder()
.WithDefaultEndpoint()
.WithDefaultEndpointPort(1883)
.WithClientId("Sender")
.Build();
_communicator.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(OnMessageReceived);
// Start the MQTT server
_communicator.StartAsync(options);
}
private void OnMessageReceived(MqttApplicationMessageReceivedEventArgs msg)
{
_logger.Debug("Received message from {VehicleId} on topic {Topic} with message {Message}", msg.ClientId,
msg.ApplicationMessage.Topic, msg.ApplicationMessage.ConvertPayloadToString());
}
public int PublishMessage(string topic, string payload,
MqttQualityOfServiceLevel qos = MqttQualityOfServiceLevel.ExactlyOnce, bool retain = false)
{
var message = new MqttApplicationMessageBuilder()
.WithTopic(topic)
.WithPayload(payload)
.WithQualityOfServiceLevel(qos)
.WithRetainFlag(retain)
.Build();
var result = _communicator.PublishAsync(message);
return (int) result.Result.ReasonCode;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
var count = 0;
while (!stoppingToken.IsCancellationRequested)
{
PublishMessage("TestTopic", $"Test message {count++}");
await Task.Delay(5000, stoppingToken);
}
}
Client:
class Program
{
static void Main(string[] args)
{
var mqttClientOptions = new MqttClientOptionsBuilder().WithClientId("Receiver").WithTcpServer("localhost").Build();
var client = new MqttFactory().CreateMqttClient();
client.ConnectAsync(mqttClientOptions, CancellationToken.None);
client.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(Handler);
client.UseDisconnectedHandler(async e =>
{
Console.WriteLine("### DISCONNECTED FROM SERVER ###");
await Task.Delay(TimeSpan.FromSeconds(5));
try
{
await client.ConnectAsync(mqttClientOptions, CancellationToken.None); // Since 3.0.5 with CancellationToken
}
catch
{
Console.WriteLine("### RECONNECTING FAILED ###");
}
});
client.ConnectedHandler = new MqttClientConnectedHandlerDelegate(eventArgs =>
client.SubscribeAsync(new MqttTopicFilterBuilder().WithTopic("TestTopic").Build()));
while (true)
{
Task.Delay(5000, CancellationToken.None);
}
}
private static void Handler(MqttApplicationMessageReceivedEventArgs msg)
{
Console.WriteLine("Received message from {0} on topic {1} with message {2}", msg.ClientId,
msg.ApplicationMessage.Topic, msg.ApplicationMessage.ConvertPayloadToString());
}
}
Hi, the receiver (ClientId) cannot know the sender client ID. This is not supported in MQTT. If you need this you need to move the sender ClientID into the topic, payload or user parameter yourself.
Only the server event handler shows the ClientID OR the ID of the Server (when the message was published at the server). The ClientID for the client defaults to its own ID by design.
Thanks for clarifying.
Only the server event handler shows the ClientID OR the ID of the Server (when the message was published at the server)
This might be a bug in this case since the server's clientid is always null instead of the clientid:
[11:31:57 DBG] Received message from null on topic TestTopic with message Test message 168
This is a message received by the ser er and sent from the same server. (see code sample of server)
Closing this due to obsolete library version. Please test with version 4 and reopen the ticket if the error persists.