C#实现数据采集系统-数据反写(1)MQTT订阅接收消息

C#实现数据采集系统-数据反写

实现步骤

  1. MQTT订阅,接收消息
  2. 反写内容写入通信类,添加到写入队列中 链接-消息内容处理和写入通信类队列
  3. 实现Modbustcp通信写入

具体实现

1.MQTT订阅,接收消息

Mqtt实现采集数据转发

Mqtt控制类增加订阅方法

  1. 增加一个通用的订阅方法,需要的参数是一个主题和一个委托,将主题跟对应的委托方法对应存储,然后再mqtt中订阅,收到对应的主题消息,然后执行对应的方法。
 public void SubscribeTopic(string topic, Action<string, string> topicAction)
 {
     //订阅
 }

然后需要一个键值对用于存储这个关系

 private Dictionary<string, Action<string, string>> _topicActions;

订阅方法实现:订阅主题,添加到_topicActions,如果已经连接,则直接订阅,没有连接,则等待连上的时候自动订阅,增加锁来确保订阅成功

/// <summary>
/// 订阅主题,添加到_topicActions,如果已经连接,则直接订阅
/// </summary>
/// <param name="topic"></param>
/// <param name="topicAction"></param>
public void SubscribeTopic(string topic, Action<string, string> topicAction)
{
    
    lock (_topicActionsLock)
    {
        if (!_topicActions.ContainsKey(topic))
        {
            _topicActions.Add(topic, topicAction);
            if (_mqttClient.IsConnected)
            {
                _mqttClient.SubscribeAsync(topic);
            }
        }
    }
    
}

在连接方法中,添加订阅

在这里插入图片描述

public void MqttConnect()
{
    while (!_mqttClient.IsConnected)
    {
        try
        {
            Console.WriteLine($"正在连接……");
            _mqttClient.ConnectAsync(_clientOptions).GetAwaiter().GetResult();
        }
        catch (Exception ex)
        {
            Task.Delay(1000).Wait();
            Console.WriteLine("连接mqtt服务器失败");
        }
    }
    lock (_topicActionsLock)
    {
        foreach (var item in _topicActions)
        {
            _mqttClient.SubscribeAsync(item.Key);
        }
    }

}
  1. 添加接收消息事件
 //客户端接收消息事件
 _mqttClient.ApplicationMessageReceivedAsync +=
     MqttClient_ApplicationMessageReceivedAsync;
     
     

  /// <summary>
  /// 接收消息
  /// </summary>
  /// <param name="args"></param>
  /// <returns></returns>
  private async Task MqttClient_ApplicationMessageReceivedAsync(
      MqttApplicationMessageReceivedEventArgs args
  )
  {
      try
      {
          Console.WriteLine($"收到消息:{args.ApplicationMessage.Topic}");
          if (_topicActions.ContainsKey(args.ApplicationMessage.Topic))
          {
              _topicActions[args.ApplicationMessage.Topic]
                  .Invoke(
                      args.ApplicationMessage.Topic,
                      Encoding.UTF8.GetString(args.ApplicationMessage.Payload)
                  );
          }
      }
      catch (Exception ex)
      {
          Console.WriteLine(ex.Message);
      }
  }

完整Mqtt代码

 public class MqttControllor
 {
     private MqttConfig _config;
     private string _clientId;
     MqttClientOptions _clientOptions;

     private IMqttClient _mqttClient;

     private readonly object _topicActionsLock = new object();
     private Dictionary<string, Action<string, string>> _topicActions;

     public MqttControllor(MqttConfig config, bool isAutoConnect = true)
     {
         _topicActions = new Dictionary<string, Action<string, string>>();

         _config = config;
         _clientId = config.ClientId == "" ? Guid.NewGuid().ToString() : config.ClientId;
         MqttClientOptionsBuilder optionsBuilder = new MqttClientOptionsBuilder()
             .WithTcpServer(_config.Ip, _config.Port)
             .WithCredentials(_config.Username, _config.Password)
             .WithClientId(_clientId);

         _clientOptions = optionsBuilder.Build();

         _mqttClient = new MqttFactory().CreateMqttClient();

         // 客户端连接关闭事件
         _mqttClient.DisconnectedAsync += MqttClient_DisconnectedAsync;
         //客户端接收消息事件
         _mqttClient.ApplicationMessageReceivedAsync +=
             MqttClient_ApplicationMessageReceivedAsync;
         if (isAutoConnect)
         {
             Task.Run(() =>
             {
                 MqttConnect();
             });
         }
     }

     /// <summary>
     /// 接收消息
     /// </summary>
     /// <param name="args"></param>
     /// <returns></returns>
     private async Task MqttClient_ApplicationMessageReceivedAsync(
         MqttApplicationMessageReceivedEventArgs args
     )
     {
         try
         {
             Console.WriteLine($"收到消息:{args.ApplicationMessage.Topic}");
             if (_topicActions.ContainsKey(args.ApplicationMessage.Topic))
             {
                 _topicActions[args.ApplicationMessage.Topic]
                     .Invoke(
                         args.ApplicationMessage.Topic,
                         Encoding.UTF8.GetString(args.ApplicationMessage.Payload)
                     );
             }
         }
         catch (Exception ex)
         {
             Console.WriteLine(ex.Message);
         }
     }

     private Task MqttClient_DisconnectedAsync(MqttClientDisconnectedEventArgs arg)
     {
         Console.WriteLine($"客户端已断开与服务端的连接……");
         //断开重连
         _mqttClient = new MqttFactory().CreateMqttClient();
         MqttConnect();
         return Task.CompletedTask;
     }

     public void MqttConnect()
     {
         while (!_mqttClient.IsConnected)
         {
             try
             {
                 Console.WriteLine($"正在连接……");
                 _mqttClient.ConnectAsync(_clientOptions).GetAwaiter().GetResult();
             }
             catch (Exception ex)
             {
                 Task.Delay(1000).Wait();
                 Console.WriteLine("连接mqtt服务器失败");
             }
         }
         Console.WriteLine($"客户端已连接到服务端……");
         //连接成功,订阅主题
         lock (_topicActionsLock)
         {
             foreach (var item in _topicActions)
             {
                 _mqttClient.SubscribeAsync(item.Key);
             }
         }
     }

     /// <summary>
     /// 订阅主题,添加到_topicActions,如果已经连接,则直接订阅
     /// </summary>
     /// <param name="topic"></param>
     /// <param name="topicAction"></param>
     public void SubscribeTopic(string topic, Action<string, string> topicAction)
     {
         lock (_topicActionsLock)
         {
             if (!_topicActions.ContainsKey(topic))
             {
                 _topicActions.Add(topic, topicAction);
                 if (_mqttClient.IsConnected)
                 {
                     _mqttClient.SubscribeAsync(topic);
                 }
             }
         }
     }

     /// <summary>
     /// 推送消息
     /// </summary>
     /// <param name="topic">主题</param>
     /// <param name="data">消息内容</param>
     /// <param name="qsLevel"></param>
     /// <param name="retain"></param>
     public void Publish(string topic, string data, int qsLevel = 0, bool retain = false)
     {
         qsLevel = Math.Clamp(qsLevel, 0, 2);

         if (!_mqttClient.IsConnected)
         {
             throw new Exception("mqtt未连接");
         }
         var message = new MqttApplicationMessage
         {
             Topic = topic,
             PayloadSegment = Encoding.UTF8.GetBytes(data),
             QualityOfServiceLevel = (MqttQualityOfServiceLevel)qsLevel,
             Retain = retain // 服务端是否保留消息。true为保留,如果有新的订阅者连接,就会立马收到该消息。
         };

         _mqttClient.PublishAsync(message);
     }
 }

  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 基于NBIOT的数据采集系统,使用MQTT协议,具体的设计和实现如下: 1. 系统设计 系统主要包括NBIOT模块、传感器、MQTT客户端和MQTT服务器。 NBIOT模块:用于与服务器建立连接,将采集的数据上传到服务器。 传感器:用于采集环境数据,如温度、湿度、光照强度等。 MQTT客户端:用于将采集的数据发送到MQTT服务器。 MQTT服务器:用于接收和存储采集的数据,并提供数据查询接口。 2. 系统实现 2.1. 硬件连接 将NBIOT模块和传感器连接到单片机上,通过单片机的IO口读取传感器数据,并通过NBIOT模块上传数据MQTT服务器。 2.2. MQTT协议 MQTT协议是一种轻量级的消息传输协议,具有易于实现、低带宽、低功耗等特点,非常适合NBIOT数据采集系统使用。 2.3. MQTT客户端 在单片机上实现MQTT客户端,采用MQTT协议将采集的数据发送到MQTT服务器。 2.4. MQTT服务器 选择一款支持MQTT协议的服务器,如EMQX、Mosquitto等,接收和存储采集的数据,并提供数据查询接口。 3. 系统流程 系统的流程如下: 1. 初始化NBIOT模块和传感器。 2. 建立NBIOT连接。 3. 读取传感器数据。 4. 将采集的数据通过MQTT协议发送到MQTT服务器。 5. MQTT服务器接收并存储数据。 6. 提供数据查询接口。 4. 总结 本文介绍了基于NBIOT的数据采集系统的设计和实现,使用MQTT协议进行数据传输,具有易于实现、低带宽、低功耗等特点,非常适合NBIOT数据采集系统使用。 ### 回答2: 基于NBIoT的数据采集系统的设计与实现,使用MQTT协议,可以按照以下步骤进行: 1. 系统设计:首先确定需要采集的数据类型和传感器种类。根据实际需求,设计传感器节点的数量和位置;确定MQTT服务器的搭建方式和网络拓扑结构。 2. 硬件选择:根据采集要求和传感器类型选择合适的NBIoT模块和相应的传感器。确保模块支持MQTT协议,并与传感器相兼容。 3. 系统搭建:将NBIoT模块连接到MQTT服务器,并进行相应的配置。确保模块与服务器之间建立稳定的连接。 4. 数据采集:使用合适的传感器将环境数据采集到NBIoT模块中。根据传感器数据类型,采用相应的数据处理算法对数据进行处理和优化。 5. 数据传输:NBIoT模块将采集到的数据通过MQTT协议封装为消息,发送到MQTT服务器。确保数据传输的稳定和高效。 6. 数据存储和处理:MQTT服务器接收数据后,可以将数据存储到数据库中,以便后续的数据分析和处理。根据实际需求,设计合适的数据处理算法,如实时监测、统计分析等。 7. 数据展示:通过前端界面或移动应用程序,将采集到的数据进行展示和分析。可以使用各种图表、表格等形式实现可视化效果,方便用户查看和分析数据。 8. 系统优化:根据实际应用中的问题和反馈,对系统进行优化和改进。例如,提升数据采集精度、减少能耗、增强系统安全性等方面进行优化。 综上所述,基于NBIoT的数据采集系统的设计与实现,使用MQTT协议,涉及硬件选择、系统搭建、数据采集数据传输、数据存储和处理、数据展示等多个方面。通过合理的设计和优化,可以实现稳定、高效的数据采集与处理,满足用户的需求。 ### 回答3: 基于NBIoT的数据采集系统设计与实现使用MQTT协议能够实现高效、可靠的数据传输。首先,在设计系统时需要考虑到NBIoT的特点,如低能耗、广域覆盖等,以满足物联网应用的需求。 在系统设计方面,我们需要考虑以下几个方面: 1. 设备连接:选择合适的NB模块与传感器节点连接,确保节点能够通过NBIoT网络连接到云平台。 2. 数据采集:合理安排传感器节点的布局,确保覆盖范围内的数据能够准确采集。采集的数据可以包括温度、湿度、光照强度等环境参数,并将其转化为数字信号。 3. MQTT协议:选择使用MQTT协议实现设备与云平台之间的通信。该协议可以保证设备和云平台之间的高效、可靠地连接,并提供灵活的订阅发布机制。设备将采集到的数据通过MQTT协议上传到云平台,在云平台上进行数据处理、存储和分析。 4. 云平台:设计合适的云平台架构,能够接收、处理和存储设备上传的数据,并提供相关的服务接口。云平台可以根据应用需求,对数据进行实时分析、实时监控和数据可视化等处理。 5. 安全性和隐私保护:在数据采集和传输过程中,要确保数据的安全性和隐私保护。可以采用数据加密、身份验证等技术来保护数据的安全性。 在系统实现方面,需要完成以下几个步骤: 1. 硬件搭建:根据设计方案,搭建传感器节点和NB模块的硬件连接。 2. MQTT通信:调用相关的MQTT库或框架,来实现设备与云平台之间的MQTT通信。通过MQTT协议,设备可以向指定的主题发布数据,以及订阅云平台发布的命令和配置信息。 3. 云平台搭建:配置和部署云平台,包括消息代理、订阅发布机制、数据存储和处理模块等。确保云平台能够接收并处理设备上传的数据。 4. 数据处理与展示:根据应用需求,对云平台接收到的数据进行实时处理和展示。可以使用数据可视化工具,生成图表、报表等形式的数据展示,以方便用户分析和决策。 综上所述,基于NBIoT的数据采集系统设计与实现使用MQTT协议,可以实现设备与云平台之间的高效、可靠通信,满足物联网应用的需求。通过该系统,可以实现物联网设备数据的采集、传输、处理和展示,为用户提供更好的数据服务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海盗Sharp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值