zoukankan      html  css  js  c++  java
  • DotNet的MQTT实施

    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.
  • 相关阅读:
    线性判别分析(LDA)
    奇异值分解(SVD)
    傅里叶变换
    SVM 之非线性支持向量机
    三角函数常用公式
    协方差、样本协方差和协方差矩阵
    方差和样本方差
    SVM 之线性支持向量机
    参考资料汇总
    QObject: Cannot create children for a parent that is in a different thread
  • 原文地址:https://www.cnblogs.com/wx881208/p/14356507.html
Copyright © 2011-2022 走看看