I have a Windows Service
running on multiple boxes, and publishing messages
to the HiveMq Mqtt Broker.
Good so far.
However, I noticed that when I manually STOP one of those Win Services - my browser Mqtt client IMMEDIATELY gets the last Last Will message (which of course I'm subscribing to).
Shouldn't I be receiving the LWT message according to the configured number of seconds in the keepAlive
period, and not immediately ? Does it have to do with the retained
flag perhaps ?
I feel that I have something wrong in my LWT configuration.
Here is a snippet of my C# code (in my Win Svc) -
public ManagedMqttClientOptions WsSecureClientOptions(PublisherSubscriber pubSubType) {
// Build LWT message, then Client Options
MqttModel lastWill = new MqttModel();
lastWill.message = "BMAZZO box is OFFLINE";
lastWill.datestamp = DateTime.Now;
lastWill.status = ConnectionStatus.Offline;
LastWillMsgJson = JsonConvert.SerializeObject(lastWill, Formatting.Indented);
clientOptionsBldr = new MqttClientOptionsBuilder()
.WithClientId(".netWinSvc-BMAZZO-Pub")
.WithProtocolVersion(MqttProtocolVersion.V500)
.WithWebSocketServer("<broker-url>:8884/mqtt")
.WithCredentials("myUser", "myPswd")
.WithCleanSession(true)
.WithWillQualityOfServiceLevel(2)
.WithWillTopic('myApp\myLAN\Box\BMAZZO\Status') // LAST WILL TOPIC
.WithWillRetain(true) // RETAIN
.WithWillPayload(LastWillMsgJson) // WILL PAYLOAD
.WithKeepAlivePeriod(TimeSpan.FromSeconds(30)) // KEEP ALIVE, 30 SECS
.WithTls(
new MqttClientOptionsBuilderTlsParameters()
{
UseTls = true,
SslProtocol = System.Security.Authentication.SslProtocols.Tls12,
Certificates = new List<X509Certificate2>() { x509Cert }
});
return managedClientOptions;
}
public async Task Publish(string messageIn, string topic, IManagedMqttClient pubClient = null, ConnectionStatus status = ConnectionStatus.Unknown)
{
MqttModel message = new MqttModel();
message.message = messageIn;
message.datestamp = DateTime.Now;
message.status = status;
var payload = JsonConvert.SerializeObject(message, Formatting.Indented);
var send = new MqttApplicationMessageBuilder()
.WithTopic("myApp\myLAN\Box\BMAZZO\Status")
.WithPayload(payload)
.WithMessageExpiryInterval(86400) // seconds per day
.WithQualityOfServiceLevel(2) // QOS
.WithRetainFlag(true) // retain = true
.Build();
applog.Debug($"Mqtt Publish() to broker - message = {messageIn} / {topic} ");
await this.managedMqttClientPublisher.EnqueueAsync(send);
await this.managedMqttClientPublisher.EnqueueAsync(send);
}
Example: I stopped the Win Svc at 2023-04-25 17:30:00
, and immediately received a message in my browser that the Service was OFFLINE
minutes earlier at 2023-04-25T17:26:43
{message: 'Offline BMAZZO 10.2.23.62', status: 1, source: 'BMAZZO', datestamp: '2023-04-25T17:26:43.7074826-04:00'}
Another example: I just stopped the Service at 17:58
, and the LWT message appears to show one of the previous LWT messages (retained in the broker?).
{message: 'Offline BMAZZO 10.2.23.62', status: 1, source: 'BMAZZO', datestamp: '2023-04-25T17:47:32.4730311-04:00'}
Perhaps the WithWillRetain
flag should be set to false ?
Any thoughts or suggestions are appreciated.
Bob