Mqttnet: Publish a message from raw binary data, instead of using the MQTT-Message class

Created on 13 Oct 2020  路  3Comments  路  Source: chkr1011/MQTTnet

Hello,
for a development project I need to consume various messages that are published by another client, not developed by myself. Because the other client is not easily accessible during development their developers gave me some binary files that represent the MQTT-Messages that are published by them as they are transmitted over the TCP-Wire.

Now I would need to read these files and "stuff" them into the MQTT-Server (directly or via publishing), so that the broker forwards/publishes them as if they were received from another client.

Is there any way to convert my binary data to a Message (I guess the client/server need to have this kind of serializer/deserializer already) or could I access some internal buffer/queue of the MQTT-Server where I could place the binary data.

So what I want to do would be

var data = File.ReadAllBytes("myfile.dat");
await mqttClient.PublishAsync(data, CancellationToken.None);

instead of

var message = new MqttApplicationMessageBuilder()
    .WithTopic("MyTopic")
    .WithPayload("Hello World")
    .WithExactlyOnceQoS()
    .WithRetainFlag()
    .Build();

await mqttClient.PublishAsync(message, CancellationToken.None);

This I only for development/testing purposes, not for production !

kind regards

question

Most helpful comment

@JanEggers After some testing it turned out, that when using a raw TCP-Connection I have to implement things like "connect", "ping" etc. too - so thats some effort. Nevertheless, after digging through the sourcecode of MQTTnet I found a "hands-on" solution that allows me to load a message from file and publish it throught the MQTTClient - its not pretty, but might help someone else in that situation.

var ofd = new OpenFileDialog();
if (ofd.ShowDialog() == DialogResult.OK)
{
    var data = File.ReadAllBytes(ofd.FileName);

    using (var ms = new MemoryStream(data))
    {
        var channel = new TestMqttChannel(ms);

        var decoder = new MqttV500PacketDecoder();
        var packetReader = new MqttPacketReader(channel);
        var fixedHeaderBuffer = new byte[2];
        var fixedHeader = packetReader.ReadFixedHeaderAsync(fixedHeaderBuffer, CancellationToken.None).Result.FixedHeader;

        var converter = new MqttV500DataConverter();
        var bodyReader = new MqttPacketBodyReader(data, fixedHeader.TotalLength-fixedHeader.RemainingLength, fixedHeader.TotalLength);
        var packet = new ReceivedMqttPacket(fixedHeader.Flags, bodyReader, fixedHeader.TotalLength);
        var applicationMessage = converter.CreateApplicationMessage((MqttPublishPacket)decoder.Decode(packet));
        MQTTClient.PublishAsync(applicationMessage);
    }
}

All 3 comments

why do you want to use an mqtt client to transmit raw data? just use a raw dotnet socket connected to a broker

oh well, yeah, keep it simple, they say :-), of course that will do the trick.

thanks

@JanEggers After some testing it turned out, that when using a raw TCP-Connection I have to implement things like "connect", "ping" etc. too - so thats some effort. Nevertheless, after digging through the sourcecode of MQTTnet I found a "hands-on" solution that allows me to load a message from file and publish it throught the MQTTClient - its not pretty, but might help someone else in that situation.

var ofd = new OpenFileDialog();
if (ofd.ShowDialog() == DialogResult.OK)
{
    var data = File.ReadAllBytes(ofd.FileName);

    using (var ms = new MemoryStream(data))
    {
        var channel = new TestMqttChannel(ms);

        var decoder = new MqttV500PacketDecoder();
        var packetReader = new MqttPacketReader(channel);
        var fixedHeaderBuffer = new byte[2];
        var fixedHeader = packetReader.ReadFixedHeaderAsync(fixedHeaderBuffer, CancellationToken.None).Result.FixedHeader;

        var converter = new MqttV500DataConverter();
        var bodyReader = new MqttPacketBodyReader(data, fixedHeader.TotalLength-fixedHeader.RemainingLength, fixedHeader.TotalLength);
        var packet = new ReceivedMqttPacket(fixedHeader.Flags, bodyReader, fixedHeader.TotalLength);
        var applicationMessage = converter.CreateApplicationMessage((MqttPublishPacket)decoder.Decode(packet));
        MQTTClient.PublishAsync(applicationMessage);
    }
}
Was this page helpful?
0 / 5 - 0 ratings