DotNet的MQTT实施

发布时间 2023-03-22 21:11:41作者: dreamw

DotNet的MQTT实施

在DotNet上实施MQTT的更高层次的软件包。Es ist sogar .NET-Standard 2.0版本:
GitHub

Hier etwas Doku:

制备

以下代码显示了如何使用MqttFactory以最简单的方式创建新的MQTT客户端。

// Create a new MQTT client.
var factory = new MqttFactory();
var mqttClient = factory.CreateMqttClient();

 

客户选择

MQTT客户端的所有选项都捆绑在一个名为MqttClientOptions的类中。可以通过属性手动在代码中填充选项,但建议使用MqttClientOptionsBuilder。此类提供了一个流畅的API,并通过提供一些重载和帮助程序方法来轻松设置选项。以下代码显示了如何将构建器与几个随机选项一起使用。

复制代码
// Create TCP based options using the builder.
var options = new MqttClientOptionsBuilder()
    .WithClientId("Client1")
    .WithTcpServer("broker.hivemq.com")
    .WithCredentials("bud", "%spencer%")
    .WithTls()
    .WithCleanSession()
    .Build();
复制代码

 

TCP连接

以下代码显示了如何设置MQTT客户端的选项以利用基于TCP的连接。

// Use TCP connection.
var options = new MqttClientOptionsBuilder()
    .WithTcpServer("broker.hivemq.com", 1883) // Port is optional
    .Build();

 

安全的TCP连接

以下代码显示了如何使用TLS安全的TCP连接(属性仅设置为参考):

// Use secure TCP connection.
var options = new MqttClientOptionsBuilder()
    .WithTcpServer("broker.hivemq.com")
    .WithTls()
    .Build();

 

处理特殊证书

为了处理特殊的证书错误,可以使用特殊的验证回调(.NET Framework和netstandard)。对于UWP应用,可以使用属性。

复制代码
// For .NET Framwork & netstandard apps:
MqttTcpChannel.CustomCertificateValidationCallback = (x509Certificate, x509Chain, sslPolicyErrors, mqttClientTcpOptions) =>
{
    if (mqttClientTcpOptions.Server == "server_with_revoked_cert")
    {
        return true;
    }

    return false;
};

// For UWP apps:
MqttTcpChannel.CustomIgnorableServerCertificateErrorsResolver = o =>
{
    if (o.Server == "server_with_revoked_cert")
    {
        return new []{ ChainValidationResult.Revoked };
    }

    return new ChainValidationResult[0];
};
复制代码

 

WebSocket连接

为了使用WebSocket通信通道,需要以下代码。

// Use WebSocket connection.
var options = new MqttClientOptionsBuilder()
    .WithWebSocketServer("broker.hivemq.com:8000/mqtt")
    .Build();

 

也可以通过调用UseTls()方法来使用安全的Web套接字连接,该方法会将协议从ws://切换到wss://。通常,需要子协议,该子协议可以直接添加到URI或专用属性中。

连接中

设置MQTT客户端选项后,可以建立连接。以下代码显示了如何与服务器连接。

// Use WebSocket connection.
var options = new MqttClientOptionsBuilder()
    .WithWebSocketServer("broker.hivemq.com:8000/mqtt")
    .Build();

await client.ConnectAsync(options);

 

重新连接

如果与服务器的连接丢失,则会触发Disconnected事件。如果由于无法访问服务器等导致对ConnectAsync的调用失败,也会触发该事件。这允许仅调用ConnectAsync方法一次,并通过使用Disconnected事件来处理重试等。如果重新连接失败,则再次触发Disconnected事件。下面的代码显示了如何设置此行为,包括短暂的延迟。

复制代码
mqttClient.Disconnected += async (s, e) =>
{
    Console.WriteLine("### DISCONNECTED FROM SERVER ###");
    await Task.Delay(TimeSpan.FromSeconds(5));

    try
    {
        await mqttClient.ConnectAsync(options);
    }
    catch
    {
        Console.WriteLine("### RECONNECTING FAILED ###");
    }
};
复制代码

 

消费信息

以下代码显示了如何处理传入消息:

复制代码
mqttClient.ApplicationMessageReceived += (s, e) =>
{
    Console.WriteLine("### RECEIVED APPLICATION MESSAGE ###");
    Console.WriteLine($"+ Topic = {e.ApplicationMessage.Topic}");
    Console.WriteLine($"+ Payload = {Encoding.UTF8.GetString(e.ApplicationMessage.Payload)}");
    Console.WriteLine($"+ QoS = {e.ApplicationMessage.QualityOfServiceLevel}");
    Console.WriteLine($"+ Retain = {e.ApplicationMessage.Retain}");
    Console.WriteLine();
};
复制代码

 

订阅主题

一旦与服务器建立连接,就可以订阅主题。以下代码显示了MQTT客户端连接后如何订阅主题。

复制代码
client.Connected += async (s, e) =>
{
    Console.WriteLine("### CONNECTED WITH SERVER ###");

    // Subscribe to a topic
    await mqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic("my/topic").Build());

    Console.WriteLine("### SUBSCRIBED ###");
};
复制代码

 

发布消息

可以直接使用属性或使用MqttApplicationMessageBuilder创建应用程序消息。此类具有一些有用的重载,可以轻松处理不同的有效负载格式。构建器的API是流畅的API。以下代码显示了如何编写应用程序消息并发布它们:

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

await client.PublishAsync(message);
复制代码

 

不需要填写应用程序消息的所有属性。以下代码显示了如何创建非常基本的应用程序消息:

var message = new MqttApplicationMessageBuilder()
    .WithTopic("/MQTTnet/is/awesome")
    .Build();

 

RPC呼叫

MQTTnet.Extensions.Rpc扩展名(以nuget形式提供)允许发送请求并等待匹配的答复。这是通过定义一个模式来完成的,该模式使用主题将请求和响应相关联。根据客户端使用情况,可以定义超时。以下代码显示了如何发送RPC调用。

var rpcClient = new MqttRpcClient(_mqttClient);

var timeout = TimeSpan.FromSeconds(5);
var qos = MqttQualityOfServiceLevel.AtMostOnce;

var response = await rpcClient.ExecuteAsync(timeout, "myMethod", payload, qos);

 

响应请求的设备(Arduino,ESP8266等)需要解析并回复主题。以下代码显示了如何在C中实现处理程序。

复制代码
// If using the MQTT client PubSubClient it must be ensured  that the request topic for each method is subscribed like the following.
_mqttClient.subscribe("MQTTnet.RPC/+/ping");
_mqttClient.subscribe("MQTTnet.RPC/+/do_something");

// It is not allowed to change the structure of the topic. Otherwise RPC will not work. So method names can be separated using
// an _ or . but no +, # or . If it is required to distinguish between devices own rules can be defined like the following.
_mqttClient.subscribe("MQTTnet.RPC/+/deviceA.ping");
_mqttClient.subscribe("MQTTnet.RPC/+/deviceB.ping");
_mqttClient.subscribe("MQTTnet.RPC/+/deviceC.getTemperature");

// Within the callback of the MQTT client the topic must be checked if it belongs to MQTTnet RPC. The following code shows one
// possible way of doing this.
void mqtt_Callback(char *topic, byte *payload, unsigned int payloadLength)
{
    String topicString = String(topic);

    if (topicString.startsWith("MQTTnet.RPC/")) {
        String responseTopic = topicString + String("/response");

        if (topicString.endsWith("/deviceA.ping")) {
            mqtt_publish(responseTopic, "pong", false);
            return;
        }
    }
}

// Important notes:
// ! Do not send response message with the _retain_ flag set to true.
// ! All required data for a RPC call and the result must be placed into the payload.
复制代码

 

 转 https://www.cnblogs.com/wx881208/p/14356507.html