物联网协议Coap之C#基于Mozi的CoapClient调用解析

目录

前言

一、CoapClient相关类介绍

1、CoapClient类图

2、CoapClient的设计与实现

3、SendMessage解析

二、Client调用分析

1、创建CoapClient对象

2、实际发送请求

3、Server端请求响应

4、控制器寻址

总结 


前言

        在之前的博客内容中,关于在ASP.Net Core当中使用Coap协议进行开发进行一篇博文的探讨物联网协议Coap之C#基于Mozi的CoapServer实现解析。这边博文主要是讲解了在ASP .Net Core当中如何使用C#编程语言进行CoapServer的实现,对其涉及的相关类进行了简单的讲解,相信大家对其实现和协议实现由了一定的认识。但是基于C#的Client的设计与实现,以及详细的调用方式并没有进行讲解。

        本文是上篇博客的继续介绍篇,依然使用ASP .NET Core,采用C#编程语言进行开发,重点介绍CoapClient的C#代码实现以及使用Get方法实际发送请求,详细阐述与CoapServer端的交互调用。便于各位读者在使用过程中对Coap的调用机制有更深的了解和掌握。

一、CoapClient相关类介绍

        在Coap中,无论是使用Java进行开发,还是C#,或者使用PHP,必须要使用Client对象进行请求的发送,即Get、Post、Put、Delete四种请求。因此在C#中有必要对CoapClient进行一下简单介绍,同时可以对比一些在不同的编程语言中,实现上的有所区别。

1、CoapClient类图

        第一步来看一下CoapClient的类图,详细如下图所示:

         相信看过CoapServer的设计的朋友们一定记得,CoapServer的父类是什么?不记得的不要紧,下面将贴出重点代码:

 public class CoAPServer : CoAPPeer

        是的,各位没有看错,CoapServer也是CoAPPeer的子类,其实不管是客户端还是服务端,都是需要进行通讯的,二CoAPPeer就承接了这部分工作的。

        CoAPPeer是对等的,双方都需要实现协议中共同的部分。

2、CoapClient的设计与实现

        言归正传,这里还是要把CoapClient类的设计好好介绍一下,毕竟Client负责了所有终端与服务端的交互。也非常有必要介绍一下这位主角。

 public class CoAPClient : CoAPPeer{private bool _randomPort = true;private CoAPTransmissionConfig _transConfig = new CoAPTransmissionConfig();private MessageCacheManager _cacheManager;private ulong _packetReceived;//private ushort _remotePort = CoAPProtocol.Port;//private string _remotehost = "";/ <summary>/ 远端服务器地址/ </summary>//public string RemoteAddress { get { return _remotehost; } protected set { _remotehost = value; } }/ <summary>/ 远端服务器端口/ </summary>//public ushort RemotePort { get { return _remotePort; } protected set { _remotePort = value; } }/// <summary>/// 服务端回应请求/// </summary>public MessageTransmit Response;/// <summary>/// 发起请求/// </summary>public MessageTransmit Request;private byte[] _token;/// <summary>/// 统一通信Token/// </summary>public byte[] Token { get => _token; set => _token = value; }

        通过代码可以看到,在CoapClient中,定义了请求和响应对象,以及token对象。 在这个类当中,不仅定义了Client的相关属性,同时还定义了丰富的方法,基本上是围绕Get、Post、Put、Delete等四个方法当中。下面来详细介绍一下:

        以Get为例,这里就定义三个重载方法,对于实际使用过程当中几乎可以覆盖相关场景,如果您还觉得不够,可以自行扩展以更好的贴近自己的实际需求。

序号方法参数说明
1Get(string url) Get方法,默认消息类型为<see cref="CoAPMessageType.Confirmable"/>
2Get(string url, CoAPMessageType msgType)

url,地址中的要素会被分解注入到Options中

msgType消息类型

3Get(string url, CoAPMessageType msgType, IList<CoAPOption> options)

url,地址中的要素会被分解注入到Options中

msgType消息类型

options 选项集合

        当然,不论是Get还是Post方法,其底层其实都用调用SendMessage()方法,因此SendMessage才是核心的方法。

3、SendMessage解析

以下是核心的发送消息的方法,代码如下:

/// <summary>/// </summary>/// <param name="url">地址中的要素会被分解注入到Options中,参见<see cref="Get(string, CoAPMessageType, IList{CoAPOption})"/></param>/// <param name="msgType">消息类型,默认为<see cref="CoAPMessageType.Confirmable"/></param>/// <param name="msgId"></param>/// <param name="token"></param>/// <param name="method"></param>/// <param name="options"></param>/// <param name="payload"></param>/// <returns></returns>public ushort SendMessage(string url, CoAPMessageType msgType, ushort msgId, byte[] token, CoAPRequestMethod method, IList<CoAPOption> options, byte[] payload){CoAPPackage cp = new CoAPPackage{Code = method,Token = token,MesssageId = msgId,MessageType = msgType ?? CoAPMessageType.Confirmable};UriInfo uri = UriInfo.Parse(url);if (!string.IsNullOrEmpty(uri.Url)){if (cp.Code == CoAPRequestMethod.Post || cp.Code == CoAPRequestMethod.Put){cp.Payload = payload;}//注入URI信息cp.SetUri(uri);//发起通讯if (!string.IsNullOrEmpty(uri.Host)){if (options != null){foreach (var opt in options){cp.SetOption(opt.Option, opt.Value);}}SendMessage(uri.Host, uri.Port == 0 ? CoAPProtocol.Port : uri.Port, cp);}else{throw new Exception($"DNS无法解析指定的域名:{uri.Domain}");}}else{throw new Exception($"分析链接地址:{url}时出错,请检查URL地址是否合法");}return cp.MesssageId;}
序号参数名说明
1url请求地址
2msgType消息类型
3msgId消息id
4token通信令牌
5method请求方法,如get、post、put、delete等
6options选项集合
7payload请求载荷,简单理解就是请求参数包

二、Client调用分析

        CoapClient的请求调用,在C#中的实现与Java是类似的,也是要创建CoapClient对象,然后向Server端发送请求,下面会针对这个调用流程进行介绍。

1、创建CoapClient对象

        创建client对象的关键代码如下:

CoAPClient cc = new CoAPClient();
//本地端口
cc.SetPort(12340);cc.Response += new MessageTransmit((x, y, z) => {Console.ForegroundColor = ConsoleColor.DarkGreen;Console.WriteLine(z.ToString(CoAPPackageToStringType.HttpStyle));Console.ForegroundColor = ConsoleColor.Gray;
});
cc.Request += new MessageTransmit((x, y, z) =>
{Console.WriteLine(z.ToString(CoAPPackageToStringType.HttpStyle));
});cc.Start();

         这里与CoapServer的启动流程是一样的,同样会创建Udp的Socket,然后绑定endPoint。这样即完成了CoapClient对象的创建及启动准备。

2、实际发送请求

        在创建了Client对象和启动后,即可进行相应方法的调用。下面以get方法为例,调用一个之前我们用C#写好的一个Resource,访问代码如下:

cc.Get("coap://127.0.0.1:5683/core/time?type=1",CoAPMessageType.Confirmable);

         然后调用下面的消息发送方法进行消息的发送。

 调用Socket对象进行消息的发送。

3、Server端请求响应

        以上步骤一个请求就已经发往了Server,下面来看一下Server端的Resoure寻址过程。首先在CoapServer当中,有一个Socket_AfterReceiveEnd的方法,用来接收请求,如下过程进行请求包的一个解析和转换。

         这里很关键,这里就是把之前通过ResourceManager管理器统一管理的控制器进行获取,类似与Java当中反射和IOC的概念。这里千万要理解。

4、控制器寻址

        在上面的过程当中会调用Invoke方法进行反射调用方法,下面来具体看一下控制器寻址怎么实现的。首先在Invoke的之后,实际会调用下面的管理器核心方法。

        这个方法是定义在ResourceManager这个类当中的。然后根据请求路径去IOC容器中寻找匹配的资源对象。

 随后完成实际方法的调用,一气呵成。这种调用方法与java的反射有异曲同工之处。

总结 

        以上就是本文的主要内容, 本文是上篇博客的继续介绍篇,依然使用ASP .NET Core,采用C#编程语言进行开发,重点介绍CoapClient的C#代码实现以及使用Get方法实际发送请求,详细阐述与CoapServer端的交互调用。便于各位读者在使用过程中对Coap的调用机制有更深的了解和掌握。行文仓促,难免有疏漏和不当之处,如果不足,欢迎各位朋友在评论区之处。

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

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

相关文章

node.js 分布式锁看这篇就够用了

Redis SETNX 命令背后的原理探究 当然&#xff0c;让我们通过一个简单的例子&#xff0c;使用 Redis CLI&#xff08;命令行界面&#xff09;来模拟获取锁和释放锁的过程。 在此示例中 获取锁: # 首先&#xff0c;设置锁密钥的唯一值和过期时间(秒) 127.0.0.1:6379> SET …

数字三角形(很经典的动态规划问题)

给定一个如下图所示的数字三角形&#xff0c;从顶部出发&#xff0c;在每一结点可以选择移动至其左下方的结点或移动至其右下方的结点&#xff0c;一直走到底层&#xff0c;要求找出一条路径&#xff0c;使路径上的数字的和最大。 73 88 1 02 7 4 4 4 5 2 6 …

第2章-神经网络的数学基础——python深度学习

第2章 神经网络的数学基础 2.1 初识神经网络 我们来看一个具体的神经网络示例&#xff0c;使用 Python 的 Keras 库 来学习手写数字分类。 我们这里要解决的问题是&#xff0c; 将手写数字的灰度图像&#xff08;28 像素28 像素&#xff09;划分到 10 个类别 中&#xff08;0…

基于多种CNN模型在清华新闻语料分类效果上的对比

该实验项目目录如图&#xff1a; 1、 模型 1.1. TextCNN # coding: UTF-8 import torch import torch.nn as nn import torch.nn.functional as F import numpy as npclass Config(object):"""配置参数"""def __init__(self, dataset, embedd…

【C++类与对象(上)】

C类与对象(上&#xff09; 1.面向过程和面向对象初步认识2.类的引入3.类的定义4.类的访问限定符及封装4.1 访问限定符4.2 封装 5.类的作用域6.类的实例化7.类的对象大小的计算7.1如何计算类对象的大小7.2 类对象的存储方式猜测7.3结构体内存对齐规则 8.类成员函数的this指针8.1…

Java多线程基础-18:线程安全的集合类与ConcurrentHashMap

Java标准库提供了很多集合类&#xff0c;但有一些集合类是线程不安全的&#xff0c;也就是说&#xff0c;在多线程环境下可能会出问题的。常用的ArrayList&#xff0c;LinkedList&#xff0c;HashMap&#xff0c;PriorityQueue等都是线程不安全的&#xff08;Vector, Stack, Ha…

Android创建工程

语言选择Java&#xff0c;我用的Java 最小SDK&#xff1a;就是开发的APP支持的最小安卓版本 Gradle 是一款Google 推出的基于 JVM、通用灵活的项目构建工具&#xff0c;支持 Maven&#xff0c;JCenter 多种第三方仓库;支持传递性依赖管理、废弃了繁杂的xml 文件&#xff0c;转而…

关于ArcGIS的Update更新工具的疑问

Update更新工具官方帮助文件解释如下&#xff1a; 但是根据这个插图很让人疑惑&#xff0c;输入要素是蓝色&#xff0c;更新要素是黄色&#xff0c;输出要素为绿色&#xff0c;而且全部是绿色。我一直以为是与更新要素相交&#xff08;被包含切割&#xff09;的哪些输入要素都被…

【常用工具】7-Zip 解/压缩软件——基本使用方法

在实际日常工作或项目中&#xff0c;经常会遇到需要在window操作系统上压缩文件&#xff0c;在Linux操作系统上解压缩的场景&#xff0c;一款实用的压缩软件迫在眉睫&#xff0c;经过实际使用总结&#xff0c;7-Zip可以很好的解决很多压缩和解压缩问题&#xff0c;其基本使用方…

WordPress如何自定义日期和时间格式?附PHP日期和时间格式字符串

WordPress网站在很多地方都需要用到日期和时间&#xff0c;那么我们应该在哪里设置日期和时间呢&#xff1f;又如何自定义日期和时间格式呢&#xff1f;下面boke112百科就跟大家一起来学习一下PHP标准化的日期和时间格式字符串。 特别说明&#xff1a;格式字符是标准化的&#…

canvas绘制旋转的大风车

查看专栏目录 canvas实例应用100专栏&#xff0c;提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重…

LCweekly-game

ExScorecomplete situation1220717/719(解答错误)30523/537(超时,弱智题已AC)40 有用的是Ex2和Ex4 Ex2 my solution class Solution { public://calculate xs l-time 幂乘int jiecheng(int x,int l){int zx;for(int i0;i<l;i){if(z>pow(10,4.5))return 0;zz*z;}return…

C#算法(11)—求三个点构成圆的圆心坐标和半径

前言 我们在上位机开发领域也经常会碰到根据三个点求出圆的圆形、半径等信息的场景,本文就是详细的介绍如何根据三个点使用C#代码求出三点构成的圆的圆心坐标、圆半径、三点构成的圆弧的角度。 1、3点求圆分析 A、B、C三个点都是圆上的坐标点,过向量AB做中垂线,过向量AC做…

What is `@Scheduled` does?

Scheduled 是Spring框架中用于定时任务调度的注解&#xff0c;它允许我们在类的方法上声明一个方法作为定时任务&#xff0c;由Spring容器统一管理和执行。使用此注解后&#xff0c;Spring会根据注解中的属性配置&#xff0c;按照指定的时间规则自动调用该方法。 public class…

文心一言 VS ChatGPT :谁是更好的选择?

前言 目前各种大模型、人工智能相关内容覆盖了朋友圈已经各种媒体平台&#xff0c;对于Ai目前来看只能说各有千秋。GPT的算法迭代是最先进的&#xff0c;但是它毕竟属于国外产品&#xff0c;有着网络限制、注册限制、会员费高昂等弊端&#xff0c;难以让国内用户享受。文心一言…

2023年度AI盘点 AIGC|AGI|ChatGPT|人工智能大模型

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 2023年是人工智能大语言模型大爆发的一年&#xff0c;一些概念和英文缩写也在这一年里集中出现&#xff0c;很容易混淆&#xff0c;甚至把人搞懵。 文章目录 前言01 《ChatGPT 驱动软件开…

使用一个定时器(timer_fd)管理多个定时事件

使用一个定时器(timer_fd)管理多个定时事件 使用 timerfd_xxx 系列函数可以很方便的与 select、poll、epoll 等IO复用函数相结合&#xff0c;实现基于事件的定时器功能。大体上有两种实现思路&#xff1a; 为每个定时事件创建一个 timer_fd&#xff0c;绑定对应的定时回调函数…

QEMU源码全解析41 —— Machine(11)

接前一篇文章&#xff1a;QEMU源码全解析40 —— Machine&#xff08;10&#xff09; 本文内容参考&#xff1a; 《趣谈Linux操作系统》 —— 刘超&#xff0c;极客时间 《QEMU/KVM》源码解析与应用 —— 李强&#xff0c;机械工业出版社 特此致谢&#xff01; 时间过去了几…

go语言(二十一)---- channel的关闭

channel不像文件一样需要经常去关闭&#xff0c;只有当你确实没有任何发送数据了&#xff0c;或者你想显示的结束range循环之类的&#xff0c;才去关闭channel。关闭channel后&#xff0c;无法向channel再发送数据&#xff0c;&#xff08;引发pannic错误后&#xff0c;导致接收…

Linux编译实时内核和打补丁

目录 1.Linux内核2.实时内核3.编译实时内核3.1 准备3.2 获取内核源码3.3 编译3.4 设置GRUB确保启动到实时内核 4.给内核打补丁5.安装新的内核 1.Linux内核 https://github.com/torvalds/linux Linux内核是Linux操作系统的核心部分&#xff0c;它是操作系统的基本组成部分&…