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

news2024/12/23 16:09:50

前言

本系列文章以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 Core
2、WebApi项目MASA.IoT.Hub,对应架构图中IoT Hub
3、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项目PubDemoSubDemo,并分别安装Dapr.ClientMasa.Contrib.Development.DaprStarter.AspNetCore后者方便我们在开发环境管理dapr的生命周期。
我们在SubDemo项目中额外安装Dapr.AspNetCore
PubDemoProgram.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/v1alpha1
kind: Component
metadata:
  name: pubsub
spec:
  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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/450696.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深入了解Synchronized同步锁的优化

大家好,我是易安!今天我们来聊一下Synchronized同步锁的优化。 在并发编程中,多个线程访问同一个共享资源时,我们必须考虑如何维护数据的原子性。 在JDK1.5之前,Java是依靠Synchronized关键字实现锁功能来做到这点的。…

Java核心技术 卷1-总结-10

Java核心技术 卷1-总结-10 通配符类型通配符概念通配符的超类型限定无限定通配符通配符捕获 通配符类型 通配符概念 通配符类型中&#xff0c;允许类型参数变化。 例如&#xff0c;通配符类型Pair<? extends Employee>表示任何泛型Pair类型&#xff0c;它的类型参数是…

LeetCode_动态规划_中等_1105.填充书架

目录 1.题目2.思路3.代码实现&#xff08;Java&#xff09; 1.题目 给定一个数组 books &#xff0c;其中 books[i] [thicknessi, heighti] 表示第 i 本书的厚度和高度。你也会得到一个整数 shelfWidth。 按顺序将这些书摆放到总宽度为 shelfWidth 的书架上。 先选几本书放…

机器学习基本模型与算法在线实验闯关

机器学习基本模型与算法在线实验闯关 文章目录 机器学习基本模型与算法在线实验闯关一、缺失值填充二、数据标准化三、支持向量机分类模型及其应用四、逻辑回归模型及其应用五、神经网络分类模型及其应用六、线性回归模型及其应用七、神经网络回归模型及其应用八、支持向量机回…

AIGC跨过奇点时刻,亚马逊云科技展露新峥嵘

AIGC是云计算的Game changer&#xff0c;将从根本上改变云计算乃至整个科技行业的游戏规则&#xff0c;作为云计算行业的Game Rulemaker&#xff0c;亚马逊云科技也展露出新的峥嵘。4月13日&#xff0c;亚马逊云科技宣布推出生成式AI新工具&#xff0c;包括Amazon Bedrock和Ama…

Java核心技术 卷1-总结-11

Java核心技术 卷1-总结-11 Java 集合框架将集合的接口与实现分离Collection接口迭代器泛型实用方法集合框架中的接口 Java 集合框架 将集合的接口与实现分离 Java集合类库将接口&#xff08;interface&#xff09;与实现&#xff08;implementation&#xff09;分离。 例如队…

把Windows装进内存条里,提前感受超越PCIe 6.0固态的顶级体验

这两年电脑内存条是越来越白菜价了&#xff0c;看到大伙儿慢慢富足起来的内存容量&#xff0c;小忆是由衷地感到高兴。 不过话说&#xff0c;动不动 32G、64G 内存你真能用得完吗&#xff1f;为了榨干大家真金白银买来的空闲内存价值。 咱这期整个骚操作——将 Windows 11 系统…

虚拟机安装linux系统centos(保姆级)

虚拟机安装linux系统centos 1.软硬件准备2.虚拟机准备1.打开VMware选择新建虚拟机2.典型安装与自定义安装3.虚拟机兼容性选择4.选择稍后安装操作系统5.操作系统的选择7.处理器与内存的分配8.网络连接类型的选择&#xff0c;网络连接类型一共有桥接、NAT、仅主机和不联网四种。9…

ArcMap气温数据插值处理

一、插值数据处理 1.先把气温excel在excel中另存为气温.csv&#xff08;网盘链接中有转好的csv文件&#xff09;&#xff0c;导入数据江苏.shp和jiangsustation.shp 和气温.csv 数据在文末百度网盘链接中 2.打开jiangsustation.shp的属性表&#xff0c;连接与字段-连接-连接的…

RabbitMQ的五种工作模式

目录 前言介绍 &#xff08;1&#xff09;启动RabbitMQ &#xff08;2&#xff09;账户管理 一、简单模式 &#xff08;1&#xff09;概念 &#xff08;2&#xff09;生产者代码 &#xff08;3&#xff09;消费者代码 二、工作队列模式 &#xff08;1&#xff09;概念…

LLVM编译流程

一、LLVM 1.1 LLVM概述 LLVM是构架编译器(compiler)的框架系统,以C编写而成,用于优化以任意程序语言编写的程序的编译时间(compile-time)、链接时间(link-time)、运行时间(run-time)以及空闲时间(idle-time),对开发者保持开放,并兼容已有脚本.LLVM计划启动于2000年,最初由美国…

Dynamics 365 开启 Modern advanced find后如何创建个人视图

本篇是自己在新的环境被新的高级查找晃的没找到如何创建个人视图而发。如何在老的高级查找页面创建这里就不表了。 D365 2022 Wav1后有了新的feature叫Modern advanced find&#xff0c;开启方式如下&#xff0c;进Power Platform的管理中心&#xff0c;找到你对应的环境&#…

Java核心技术 卷1-总结-6

Java核心技术 卷1-总结-6 接口示例接口与回调Comparator接口对象克隆 lambda表达式为什么引入lambda表达式lambda表达式的语法 接口示例 接口与回调 回调&#xff08;callback&#xff09;是一种常见的程序设计模式。在这种模式中&#xff0c;可以指出某个特定事件发生时应该…

珍藏多年的MySQL函数大全笔记,掌握数据库真不难

做程序员的谁会离得开数据库呢&#xff1f;今天就来分享一下我整理的MySQL的常用函数&#xff0c;基本上囊括了平时要用的函数&#xff0c;它们已经陪我走过了不少年头了&#xff0c;风里来雨里去&#xff0c;缝缝补补又几年&#xff0c;希望能帮到你们&#xff01; 如果数据库…

短视频app开发:如何实现视频直播功能

短视频源码的实现 在短视频app开发中&#xff0c;实现视频直播功能需要借助短视频源码。短视频源码可以提供一个完整的视频直播功能模块&#xff0c;包括视频采集、编码、推流等。因此&#xff0c;我们可以选择一些开源的短视频源码&#xff0c;例如LFLiveKit、ijkplayer等&am…

Nacos简介 安装 配置

简介 什么是注册中心 注册中心在微服务项目中扮演着非常重要的角色&#xff0c;是微服务架构中的纽带&#xff0c;类似于通讯录&#xff0c;它记录了服务和服务地址的映射关系。在分布式架构中&#xff0c;服务会注册到这里&#xff0c;当服务需要调用其它服务时&#xff0c;…

RHCE(六)

目录 1.编写脚本for1.sh,使用for循环创建20账户&#xff0c;账户名前缀由用户从键盘输入&#xff0c;账户初始密码由用户输入&#xff0c;例如: test1、test2、test3、.....、 test10 &#xff08;1&#xff09;编写脚本 &#xff08;2&#xff09;运行脚本 &#xff08;3&…

机器学习——主成分分析法(PCA)概念公式及应用python实现

机器学习——主成分分析法&#xff08;PCA&#xff09; 文章目录 机器学习——主成分分析法&#xff08;PCA&#xff09;一、主成分分析的概念二、主成分分析的步骤三、主成分分析PCA的简单实现四、手写体识别数字降维 一、主成分分析的概念 主成分分析&#xff08;PCA&#x…

华为OD机试真题(Java),分班(100%通过+复盘思路)

一、题目描述 幼儿园两个班的小朋友在排队时混在了一起&#xff0c;每位小朋友都知道自己是否与前面一位小朋友是否同班&#xff0c;请你帮忙把同班的小朋友找出来。 小朋友的编号为整数&#xff0c;与前一位小朋友同班用Y表示&#xff0c;不同班用N表示。 二、输入描述 输…

Android Jetpack - Navigation 组件:进行应用程序导航

一. Navigation 组件的介绍 1.1 什么是 Navigation 组件 Navigation 组件是一种 Android Jetpack 库&#xff0c;它可以帮助开发者轻松地实现应用程序中的导航功能。导航组件包含多个类和组件&#xff0c;包括导航图、目的地、导航控制器等&#xff0c;可以帮助我们管理应用程…