写点什么

使用 MASA 全家桶从零开始搭建 IoT 平台(一)环境准备

  • 2023-04-23
    浙江
  • 本文字数:3647 字

    阅读完需:约 12 分钟

使用MASA全家桶从零开始搭建IoT平台(一)环境准备

前言

本系列文章以 IoT 开发小白的角度,从零开始使用.Net 为主要技术搭建一个简单的 IoT 平台,由于是入门系列,所有代码以围绕 IoT 基础业务场景为主,不会涉及 DDD 等设计思想。

架构图

这里是我们整个 IoT 平台的架构图。


一、设备接入

1、针对可以联网的设备,直接通过 MQTT 协议连接到我们的 MQTT 服务上(可以使用国内的阿里云、Onenet 也可以使用开源 EMQX 实现)。绿色线框部分 2、针对不能联网的设备,例如只能通过红外、短信、等其他非互联网技术通讯的,采用设备网关统一接管,这里主要涉及硬件相关内容我们不深入讨论。橙色线框部分

二、处理设备遥测数据

我们通过 MQTT Hub 订阅设备发布到 MQTT 的消息,并通过 Dapr 的 Pub/Sub 方式发送给我们的 IoT Core 集群,我们可以通过 MQTT 5.0 协议中的共享订阅方式实现我们高可用集群。蓝色线框部分

三、设备控制

直接在 IoT Core 中直接向 MQTT 发布控制指令。红色箭头所示

四、管理后台

管理后台我们采用 Blazor 搭建结合 MASA Auth 实现权限控制,红色线框部分,在 IoT Core 和 IoT UI 中间有一层 Gateway,主要是方便我们在这一层 Mock 一些依赖的第三方业务接口,例如某个环节我需要从生产的 MES 系统获取某些信息才能继续下面的操作,我们可以在 Gateway 层去 Mock 这些接口和数据,方便我们测试。

五、数据存储

业务数据我们存储到关系型数据库中,设备的消息数据(遥测数据),我们存储到时序库中,方便统计查找,和生成报表。

六、规则引擎

针对不同类型的消息,我们可以在规则引擎中配置,使消息可以走不同的处理流程,例如接入的第三方系统设备,设备消息可能是加密的,我们就通过规则引擎将这种类型的消息发送到第三方系统解密之后再存储到数据库中,也可以在这里针对遥测数据进行分析和过滤,产生分级告警信息,发送到对应的处理系统或者干系人邮箱等。

环境准备

1、安装 EMQX

1、运行以下命令获取 Docker 镜像:


docker pull emqx/emqx:5.0.20
复制代码


2、运行以下命令启动 Docker 容器


docker run -d --name emqx -p 1883:1883 -p 8083:8083 -p 8084:8084 -p 8883:8883 -p 18083:18083 emqx/emqx:5.0.20
复制代码

2、创建解决方案

创建解决方案 MASA.IoT,分别添加 1、WebApi 项目 MASA.IoT.Core,对应架构图中 IoT Core2、WebApi 项目 MASA.IoT.Hub,对应架构图中 IoT Hub3、Blazor 应用 MASA.IoT.UI,对应架构图中的 IoT.UI,也就是管理后台 4、类库 MASA.IoT.Common,存放一些静态的公共方法

3、安装 Dapr 开发环境

Dapr 的全称是 “Distributed Application Runtime”,即 “分布式应用运行时”。是一个开源项目,由微软发起对 Dapr 不了解的同学可以学习,鬼老师的 Dapr 系列文章

使用 Masa DaprStarter 搭建开发环境

安装 Dapr

Windows 安装 Dapr 的方式有很多,可以参考官方文档


https://docs.dapr.io/getting-started/install-dapr-cli/


国内如果访问缓慢,建议直接下载 msi 文件安装


https://github.com/dapr/cli/releases



安装一路下一步即可。

安装 Docker Desktop

直接参考官方文档,这里不过多赘述


https://docs.docker.com/desktop/install/windows-install/

初始化 Dapr

命令行执行


dapr init
复制代码



这里如果有类似网络错误,那就需要考虑魔法上网或者直接到 dapr 的 github 上下载 dashboard_darwin_amd64.zip daprd_windows_amd64.zip 两压缩包,执行 dapr init 有了 bin 目录后 看准时机 把下载好的两个压缩包复制进去例如:C:\Users\Administrator\.dapr 下的 bin 目录中,该目录下的压缩包会自动解压如果失败可以通过 dapr uninstall 命令卸载后重试。安装成功后通过 dapr -v 可以看到如下版本信息



在 Docker Desktop 中会创建三个容器


代码开发

我们新建两个 WebApi 项目,模拟微服务之间通过 dapr 调用的场景。新建 webapi 项目 PubDemo SubDemo,并分别安装 Dapr.Client Masa.Contrib.Development.DaprStarter.AspNetCore 后者方便我们在开发环境管理 dapr 的生命周期。我们在 SubDemo 项目中额外安装 Dapr.AspNetCore。在 PubDemo Program.cs 添加


if (builder.Environment.IsDevelopment()){    builder.Services.AddDaprStarter(builder.Configuration.GetSection("DaprOptions"), false);}
复制代码


并在配置文件中添加 DaprOptions 配置


  "DaprOptions": {    "AppId": "pub-demo-webapi",    "AppPort": 18009,    "AppIdSuffix": "",    "DaprGrpcPort": 20333,    "DaprHttpPort": 20334,    "LogLevel": "debug"  }
复制代码


同样在 SubDemo 添加上述内容,注意端口号不要重复。


  "DaprOptions": {    "AppId": "sub-demo-webapi",    "AppPort": 19009,    "AppIdSuffix": "",    "DaprGrpcPort": 20233,    "DaprHttpPort": 20234,    "LogLevel": "debug"  }
复制代码


这里需要注意在 SubDemo 项目中 AppPort 需要与 launchSettings.json 中应用的启动端口保持一致,这里都是 19009,这个 AppPort 不是 dapr 的端口 而是需要与 dapr sidecar 通信的应用程序的端口地址。


    "SubDemo": {      "commandName": "Project",      "dotnetRunMessages": true,      "launchBrowser": true,      "launchUrl": "swagger",      "applicationUrl": "http://localhost:19009",      "environmentVariables": {        "ASPNETCORE_ENVIRONMENT": "Development"      }
复制代码


SubDemo 中还需要订阅相关的配置,完整代码如下


var builder = WebApplication.CreateBuilder(args);//注册 Dapr//将 AddDapr 扩展方法附加到 AddControllers 扩展方法会注册必要的服务以将 Dapr 集成到 MVC 管道中builder.Services.AddControllers().AddDapr();if (builder.Environment.IsDevelopment()){    builder.Services.AddDaprStarter(builder.Configuration.GetSection("DaprOptions"), false);}builder.Services.AddEndpointsApiExplorer();builder.Services.AddSwaggerGen();
var app = builder.Build();if (app.Environment.IsDevelopment()){ app.UseSwagger(); app.UseSwaggerUI();}app.UseHttpsRedirection();app.UseAuthorization();// 将 CloudEvents 中间件添加到 ASP.NET Core 中间件管道中app.UseCloudEvents();app.MapControllers();// 终结点路由配置中对 MapSubscribeHandler 的调用会将 Dapr 订阅终结点添加到应用程序。app.MapSubscribeHandler();app.Run();
复制代码


注意这里,app.MapSubscribeHandler();此终结点将响应 /dapr/subscribe 上的请求。 调用此终结点时,它将自动查找使用 Topic 属性修饰的所有 WebAPI 操作方法,并指示 Dapr 为这些方法创建订阅。我们在 SubDemo 新建一个 WebApi 接口来订阅 Pub 数据


namespace SubDemo.Controllers{    [Route("api/[controller]")]    [ApiController]    public class SubTestController : ControllerBase    {        [Topic("pubsub", "testdata")]        [HttpPost("testdata")]        public void TestData([FromBody] string testStrData)        {            Console.WriteLine("Subscriber received : " + testStrData);        }    }}
复制代码


这里 Topic 第一个参数为 pubsub 组件名称,第二个参数为订阅的主题名称。默认的 pubsub 组件配置在 C:\Users\Administrator.dapr\components 目录下。


apiVersion: dapr.io/v1alpha1kind: Componentmetadata:  name: pubsubspec:  type: pubsub.redis  version: v1  metadata:  - name: redisHost    value: localhost:6379  - name: redisPassword    value: ""
复制代码


SubDemo 编写完毕,接下来再 PubDemo 中添加一个测试 Api


using Dapr.Client;using Microsoft.AspNetCore.Mvc;
namespace PubDemo.Controllers{ [Route("api/[controller]")] [ApiController] public class PubTestController : ControllerBase { private readonly Dapr.Client.DaprClient daprClient; public PubTestController() { daprClient = new DaprClientBuilder().Build(); } [HttpPost] public async Task PostTestDataAsync([FromBody] string testStrData) { await daprClient.PublishEventAsync("pubsub", "testdata", testStrData); } }}
复制代码


这里直接通过 PublishEventAsync 方法向 testdata 写入一条文本信息。

测试效果

我们同时启动 SubDemo 和 PubDemo 两个项目。应用完全启动后,在命令行通过 dapr list 可以看到 DaprStarter 已经帮我们启动好了两个 dapr 实例。



在 SubDemo 的日志中,我们可以看到 Dapr 启动和订阅成功的日志



我们调用 PubDemo 中的测试 Api,可以在 SubDemo 的日志看到消费成功的日志



也可以在 redis 中看到对应的记录



我们打开 zipkin 还可以看到链路信息。这里仅作演示,后面我们会接入强大的 MASA Stack 全家桶,使用其中的 TSC 服务分析链路信息会更方便和直观。




还可以查看依赖关系,非常方便。



全文结束。以上就是今天要讲的内容,本文仅仅简单介绍了我们 IoT 后台的基本架构,下一章我们讲设备的生命周期


如果你对我们的 MASA Framework 感兴趣,无论是代码贡献、使用、提 Issue,欢迎联系我们

WeChat:MasaStackTechOps

QQ:7424099

发布于: 刚刚阅读数: 3
用户头像

还未添加个人签名 2021-10-26 加入

MASA技术团队官方账号,我们专注于.NET现代应用开发解决方案,Wechat:MasaStackTechOps ,Website:www.masastack.com

评论

发布
暂无评论
使用MASA全家桶从零开始搭建IoT平台(一)环境准备_.net_MASA技术团队_InfoQ写作社区