线上测试木舟物联网平台之如何通过HTTP网络组件接入设备

news/2025/3/12 8:40:09/文章来源:https://www.cnblogs.com/fanliang11/p/18766635

一、概述 

木舟 (Kayak) 是什么?

       木舟(Kayak)是基于.NET6.0软件环境下的surging微服务引擎进行开发的, 平台包含了微服务和物联网平台。支持异步和响应式编程开发,功能包含了物模型,设备,产品,网络组件的统一管理和微服务平台下的注册中心,服务路由,模块,中间服务等管理。还有多协议适配(TCP,MQTT,UDP,CoAP,HTTP,Grpc,websocket,rtmp,httpflv,webservice,等),通过灵活多样的配置适配能够接入不同厂家不同协议等设备。并且通过设备告警,消息通知,数据可视化等功能。能够让你能快速建立起微服务物联网平台系统。

     那么下面就为大家介绍如何从创建组件、协议、设备网关,设备到设备网关接入,再到设备数据上报,把整个流程通过此篇文章进行阐述。

木舟物联网平台:http://117.72.121.2:3100

      surging 微服务引擎开源地址:https://github.com/fanliang11/surging(后面surging 会移动到microsurging进行维护)

二、木舟物联网平台管理平台界面

      用户名:fanly  密码:123456

 三、链路跟踪监控

地址:http://117.72.121.2:8080/ (这是社区版,仅支持v6.0 ,企业版本支持v8.0)

 

 

四、网络组件

1.编辑创建HTTP协议的网络组件,可以选择共享配置和独立配置(独立配置是集群模式),然后可以选择开启swagger和webservice.

 

 开启成功后,可以看看swagger 是否可以访问

 

地址:http://117.72.121.2:281/swagger/index.html

 开启成功后,可以看看webservice是否可以访问

webservice:http://117.72.121.2:168/devicedata/devicedata/changedevicestage.asmx?servicekey=WebService

 五、自定义协议

  • 如何创建自定义协议模块

如果是网络编程开发,必然会涉及到协议报文的编码解码处理,那么对于平台也是做到了灵活处理,首先是协议模块创建,通过以下代码看出协议模块可以添加协议说明md文档, 身份鉴权处理,HTTP路由,消息编解码,元数据配置。下面一一介绍如何进行编写

复制代码
  public class Demo5ProtocolSupportProvider : ProtocolSupportProvider{public override IObservable<ProtocolSupport> Create(ProtocolContext context){
      var support = new ComplexProtocolSupport();
    support.Id = "demo5";
    support.Name = "演示协议5";
    support.Description = "演示协议5";support.AddDocument(MessageTransport.Http, "Document/document-http.md");support.AddAuthenticator(MessageTransport.Http, new Demo5Authenticator()); support.AddRoutes(MessageTransport.Http, new List<BasicMessageCodec>() {BasicMessageCodec.DeviceOnline,BasicMessageCodec.ReportProperty,BasicMessageCodec.WriteProperty,BasicMessageCodec.ReadProperty,BasicMessageCodec.Event}.Select(p => HttpDescriptor.Instance(p.Pattern).GroupName(p.Route.GroupName()).HttpMethod(p.Route.HttpMethod()).Path(p.Pattern).ContentType(MediaType.ToString(MediaType.ApplicationJson)).Description(p.Route.Description()).Example(p.Route.Example())).ToList());support.AddMessageCodecSupport(MessageTransport.Http, () => Observable.Return(new HttpDeviceMessageCodec()));support.AddConfigMetadata(MessageTransport.Http, _httpConfig);return Observable.Return(support);}}
复制代码

1. 添加协议说明文档如代码: support.AddDocument(MessageTransport.Http, "Document/document-http.md");,文档仅支持 markdown文件,如下所示

 

复制代码
### 使用HTTP推送设备数据上报属性例子: POST /{productId}/{deviceId}/properties/report
Authorization:{产品或者设备中配置的Token}
Content-Type: application/json{"properties":{"temp":11.5}
}上报事件例子:POST /{productId}/{deviceId}/event/{eventId}
Authorization:{产品或者设备中配置的Token}
Content-Type: application/json{"data":{"createtime": ""}
}
复制代码

 

2. 添加身份鉴权如代码: support.AddAuthenticator(MessageTransport.Http, new Demo5Authenticator()) ,自定义身份鉴权Demo5Authenticator 代码如下:

 

复制代码
       public class Demo5Authenticator : IAuthenticator{public IObservable<AuthenticationResult> Authenticate(IAuthenticationRequest request, IDeviceOperator deviceOperator){var result = Observable.Return<AuthenticationResult>(default);if (request is DefaultAuthRequest){var authRequest = request as DefaultAuthRequest;deviceOperator.GetConfig(authRequest.GetTransport()==MessageTransport.Http?"token": "key").Subscribe(  config =>{var password = config.Convert<string>();if (authRequest.Password.Equals(password)){result= result.Publish(AuthenticationResult.Success(authRequest.DeviceId));}else{result= result.Publish(AuthenticationResult.Failure(StatusCode.CUSTOM_ERROR, "验证失败,密码错误"));}});}elseresult = Observable.Return<AuthenticationResult>(AuthenticationResult.Failure(StatusCode.CUSTOM_ERROR, "不支持请求参数类型"));return result;}public IObservable<AuthenticationResult> Authenticate(IAuthenticationRequest request, IDeviceRegistry registry){var result = Observable.Return<AuthenticationResult>(default);var authRequest = request as DefaultAuthRequest;registry.GetDevice(authRequest.DeviceId).Subscribe(async p => {var config=  await p.GetConfig(authRequest.GetTransport() == MessageTransport.Http ? "token" : "key");var password= config.Convert<string>();if(authRequest.Password.Equals(password)){result= result.Publish(AuthenticationResult.Success(authRequest.DeviceId));}else{result= result.Publish(AuthenticationResult.Failure(StatusCode.CUSTOM_ERROR, "验证失败,密码错误"));}});return result;}}
复制代码

 

3. 添加Http路由代码support.AddRoutes,那么如何配置呢,代码如下:

 

    public static BasicMessageCodec ReportProperty =>new BasicMessageCodec("/*/properties/report", typeof(ReadPropertyMessage), route => route.GroupName("属性上报").HttpMethod("Post").Description("上报物模型属性数据").Example("{\"properties\":{\"属性ID\":\"属性值\"}}"));

 

4.添加消息编解码代码 support.AddMessageCodecSupport(MessageTransport.Http, () => Observable.Return(new HttpDeviceMessageCodec())), 可以自定义编解码,HttpDeviceMessageCodec代码如下:

 

复制代码
  public class HttpDeviceMessageCodec : DeviceMessageCodec{private readonly MessageTransport _transport;public HttpDeviceMessageCodec() : this(MessageTransport.Http){}private static DefaultHttpResponseMessage Unauthorized(String msg){return new DefaultHttpResponseMessage().ContentType(MediaType.ApplicationJson).Body("{\"success\":false,\"code\":\"unauthorized\",\"message\":\"" + msg + "\"}").Status(HttpStatus.AuthorizationFailed);}private static DefaultHttpResponseMessage BadRequest(){return new DefaultHttpResponseMessage().ContentType(MediaType.ApplicationJson).Body("{\"success\":false,\"code\":\"bad_request\"}").Status(HttpStatus.RequestError);}public HttpDeviceMessageCodec(MessageTransport transport){_transport = transport;}public override IObservable<IDeviceMessage> Decode(MessageDecodeContext context){if (context.GetMessage() is HttpRequestMessage){return DecodeHttpRequestMessage(context);}return Observable.Return<IDeviceMessage>(default);}public override  IObservable<IEncodedMessage> Encode(MessageEncodeContext context){return Observable.Return<IEncodedMessage>(default);}private IObservable<IDeviceMessage> DecodeHttpRequestMessage(MessageDecodeContext context){var result = Observable.Return<IDeviceMessage>(default);var message = (HttpExchangeMessage)context.GetMessage();Header? header = message.Request.GetHeader("Authorization");if (header == null || header.Value == null || header.Value.Length == 0){message.Response(Unauthorized("Authorization header is required")).ToObservable().Subscribe(p => result = result.Publish(default));return result;}var httpToken = header.Value[0];var paths = message.Path.Split("/");if (paths.Length == 0){message.Response(BadRequest()).ToObservable().Subscribe(p => result = result.Publish(default));return result;}String deviceId = paths[1];context.GetDevice(deviceId).Subscribe(async deviceOperator =>{var config = deviceOperator==null?null: await deviceOperator.GetConfig("token");var token = config?.Convert<string>();if (token == null || !httpToken.Equals(token)){await message.Response(Unauthorized("Device not registered or authentication failed"));}else{var deviceMessage = await DecodeBody(message, deviceId);if (deviceMessage != null){await message.Success("{\"success\":true,\"code\":\"success\"}");result = result.Publish(deviceMessage);}else{await message.Response(BadRequest());}}});return result;}private async Task<IDeviceMessage> DecodeBody(HttpExchangeMessage message,string deviceId){byte[] body = new byte[message.Payload.ReadableBytes];message.Payload.ReadBytes(body);var deviceMessage = await TopicMessageCodec.Dodecode(message.Path, body);deviceMessage.DeviceId = deviceId;return deviceMessage;}}
复制代码

 

5.添加元数据配置代码 support.AddConfigMetadata(MessageTransport.Http, _httpConfig);  _httpConfig代码如下

        private readonly DefaultConfigMetadata _httpConfig = new DefaultConfigMetadata("Http认证配置", "token为http认证令牌").Add("token", "token", "http令牌", StringType.Instance);
  • 如何加载协议模块,协议模块包含了协议模块支持添加引用加载和上传热部署加载。                           

   引用加载模块

 上传热部署协议模块

 六、设备网关

创建设备网关

 七、产品管理

以下是添加产品。

 设备接入

 八、设备管理

添加设备

 HTTP认证配置

 创建告警阈值

 九、测试

 利用Postman 进行测试,以调用http://117.72.121.2:168/{productid}/{deviceid}/properties/report 为例,Authorization设置:123456

测试地址:http://117.72.121.2:168/product-http-23/DJI-Mavic-v231x12/properties/report

1.正常数据测试

 

 

 

 2. 如果是选用Get方式调用,会因为找不到ServiceRoute而返回错误。

 

 3. 把Authorization改成1111,会返回错误Device not registered or authentication failed,从而上报数据失败

 

 以上上传的数据可以在设备信息-》运行状态中查看

 告警信息可以在超临界数据中查看

四、结尾

        如果感兴趣可以联系作者开通端口进行测试,后面陆续会把协议接入到木舟物联网平台,到时候可以支持多终端操作可视化管理。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

经过 10 亿级性能验证的隐私计算开源利器

在数据驱动的时代,我们每天都在产生大量数据:购物记录、健康信息、社交关系……这些数据蕴含巨大价值,但也伴随着隐私泄露的风险。 试想一下:医院希望联合研究某种疾病,但患者数据无法直接共享。 银行想合作分析反欺诈信息,但客户隐私数据必须严格保护。 AI 公司需要使用…

值得推荐的IT公司名单(国企篇)

大家好,今天我们来盘点一下值得推荐的国企,这些企业在行业内具有举足轻重的地位,不仅主营业务突出,福利待遇优厚,尤其是研发岗位的薪资区间,更是让人眼前一亮。十大顶尖央企国企,待遇优厚如天花板级别!(排名不分先后)1、中国烟草总公司 人家都说能成为烟草总公司的一…

Entity Framework Core 数据库迁移

EF Core 通过两种方式来保持**模型**和**数据库架构**同步。 迁移 Code First 反向工程 Db First 管理迁移 通过EF Core 命令行工具来管理迁移 安装EF Core 命令行工具# 安装 dotnet-ef dotnet tool install --global dotnet-ef# 验证安装 dotnet ef# 更新工具 dotnet tool upd…

Roslyn 分析器已知问题 传递项目属性时将忽略分号之后的内容

本文记录 Roslyn 分析器、源代码生成器的已知问题,通过CompilerVisibleProperty 传递值时,所有在 `;`、`#` 和换行符之后的字符都会被忽略相关问题链接:https://github.com/dotnet/roslyn/issues/43970 https://github.com/dotnet/roslyn/issues/51692此问题由 walterlv 发现…

Avalonia 已知问题 继承滚动条将让里层控件无法获得无穷大空间

本文记录 Avalonia 的一个已知问题,如果有代码里面编写一个类型继承 ScrollViewer 类型,然后这个类型里面啥都不做。那将会导致所有放在此滚动条里面的控件无法获取无穷大的空间,其宽高无法撑开,被限定为上层容器尺寸复现步骤如下:新建一个 FooScrollViewer 类型,让其继承…

读DAMA数据管理知识体系指南17数据存储和操作治理

读DAMA数据管理知识体系指南17数据存储和操作治理1. 管理数据库性能 1.1. 数据库的性能取决于两个相互依赖的因素:可用性和响应速度 1.2. 性能包括确保空间的可用性、查询优化以及其他能使数据库以有效的方式返回数据的因素1.2.1. 如果没有可用性,就无法衡量数据库的性能1.2.…

干货分享!厦大140页PPT读懂大模型,从概念到实践

干货分享!厦大140页PPT读懂大模型 《厦门大学:大模型概念、技术与应用实践》 是由厦门大学大数据教学团队出品的DeepSeek科普类内容。文章涵盖:人工智能发展简史 人工智能思维 大模型:人工智能的前沿 AIGC应用与实践内容分享:引言 在数字化浪潮汹涌澎湃的当下,大模型如同…

一款基于.NET开源、强大的网络管理和网络问题排查工具!

前言 今天大姚给大家分享一款基于.NET开源、免费、功能强大的网络管理和网络问题排查工具:NETworkManager。 项目介绍 NETworkManager 是一个基于.NET开源(GPL-3.0 license)、免费、功能强大的开源工具,旨在帮助用户管理和解决网络问题。通过提供一系列网络连接和管理工具,…

Palera1n之苹果手机越狱,iOS15~iOS 18有根越狱方法

iOS15/16/17/18越狱教程用到的工具为palra1n ,该工具支持使用Sileo商店并安装插件。其他越狱方式可参考:https://www.cnblogs.com/codtina/可以添加对其他 arm64 Darwin 设备的支持,包括 Apple TV、HomePod 和 Darwin 21 及更高版本上的 iBridge,但目前不受支持。 永远不会支…

Palera1n苹果手机越狱,iOS15~iOS 18有根越狱方法

iOS15/16/17/18越狱教程用到的工具为palra1n ,该工具支持使用Sileo商店并安装插件。其他越狱方式可参考:https://www.cnblogs.com/codtina/可以添加对其他 arm64 Darwin 设备的支持,包括 Apple TV、HomePod 和 Darwin 21 及更高版本上的 iBridge,但目前不受支持。 永远不会支…

Palera1n iOS15.8.2~iOS 18有根越狱教程

iOS15/16/17/18越狱教程用到的工具为palra1n ,该工具支持使用Sileo商店并安装插件。可以添加对其他 arm64 Darwin 设备的支持,包括 Apple TV、HomePod 和 Darwin 21 及更高版本上的 iBridge,但目前不受支持。 永远不会支持 arm64e 设备。A11设备在使用前需要关闭锁屏密码,如…