物联网协议Coap之Californium CoapServer解析

目录

前言

一、CoapServer对象

1、类对象定义

2、ServerInterface接口

3、CoapServer对象

 二、CoapServer服务运行分析

1、CoapServer对象实例化

1.1 调用构造方法

1.2 生成全局配置

1.3 创建Resource对象

1.4-1.8、配置消息传递器、添加CoapResource

1.9-1.12 创建线程池

1.3-1.7 端口绑定、服务配置

2、添加处理器

3、服务启动

 1.1-1.5、绑定端口及相关服务

1.7-1.8 循环启动EndPoint

4、服务运行

总结


前言

        在之前的博客物联网协议之COAP简介及Java实践中,我们采用使用Java开发的Californium框架下进行Coap协议的Server端和Client的协议开发。由于最基础的入门介绍博客,我们没有对它的CoapServer的实现进行深层次的分析。众所周知,Coap和Http协议类似,是分为Server端和Client端的,Server负责接收请求,同时负责业务请求的的处理。而Client负责发起服务,同时接收Server端返回的响应。

        这里将首先介绍CoapServer的内容,本文将采用OOP的设计方法对Californium中Server的实现和启动进行源码级的分析,让读者对Coap的实现有进一步的了解,帮助掌握其设计和实现细节。

一、CoapServer对象

        CoapServer对象是Californium中的核心对象,主要功能作用是创建一个Coap协议的服务端,在指定端口和设置资源处理控制器后,就可以用于接收来自客户端的请求。CoapServer的基本架构如下:

* +------------------------------------- CoapServer --------------------------------------+* |                                                                                       |* |                               +-----------------------+                               |* |                               |    MessageDeliverer   +--> (Resource Tree)            |* |                               +---------A-A-A---------+                               |* |                                         | | |                                         |* |                                         | | |                                         |* |                 .-------->>>------------' | '--------<<<------------.                 |* |                /                          |                          \                |* |               |                           |                           |               |* |             * A                         * A                         * A               |* | +-----------------------+   +-----------------------+   +-----------------------+     |* | |        Endpoint       |   |        Endpoint       |   |      Endpoint         |     |* | +-----------------------+   +-----------------------+   +-----------------------+     |* +------------v-A--------------------------v-A-------------------------v-A---------------+*              v A                          v A                         v A            *              v A                          v A                         v A         *           (Network)                    (Network)                   (Network)* 

1、类对象定义

        首先我们来看一下CoapServer的类图,从它的类图看一下涉及的类的实现关系。具体如下图所示:

         从上图可以很清晰的看到CoapServer对象的依赖关系,它是ServerInterface的实现类,内部定义了RootResource,它是CoapResource的一个子类。

2、ServerInterface接口

        ServerInterface接口中定义了CoapServer的方法,比如启动、停止、移除、添加服务实例、销毁、addEndpoint等等。来看看其具体的定义:


package org.eclipse.californium.core.server;
import java.net.InetSocketAddress;
import java.util.List;
import org.eclipse.californium.core.network.Endpoint;
import org.eclipse.californium.core.server.resources.Resource;public interface ServerInterface {/*** 启动服务*/void start();/***停止服务*/void stop();/*** 销毁服务*/void destroy();/*** 增加资源到服务实例中*/ServerInterface add(Resource... resources);/*** 从服务实例中移除资源*/boolean remove(Resource resource);void addEndpoint(Endpoint endpoint);List<Endpoint> getEndpoints();Endpoint getEndpoint(InetSocketAddress address);Endpoint getEndpoint(int port);}
序号方法说明
1void start();Starts the server by starting all endpoints this server is assigned to Each endpoint binds to its port. If no endpoint is assigned to the  server, the server binds to CoAP's default port 5683.
2void stop();Stops the server, i.e. unbinds it from all ports.
3void destroy();Destroys the server, i.e. unbinds from all ports and frees all system resources.
4ServerInterface add(Resource... resources); Adds one or more resources to the server.
5boolean remove(Resource resource); Adds an endpoint for receive and sending CoAP messages on.
6List<Endpoint> getEndpoints();Gets the endpoints this server is bound to.

3、CoapServer对象

        作为ServerInterface的实现子类,我们来看看Server的具体实现,首先来看下类图:

         成员属性:

序号属性说明
1 Resource rootThe root resource. 
2 NetworkConfig config网络配置对象
3MessageDeliverer delivererThe message deliverer
4List<Endpoint> endpointsThe list of endpoints the server connects to the network.
5ScheduledExecutorService executor;The executor of the server for its endpoints (can be null). 
6boolean runningfalse
7class RootResource extends CoapResource内部实现类

        成员方法除了实现ServerInterface接口的方法之外,还提供以下方法:

序号方法说明
1Resource getRoot()Gets the root of this server
2Resource createRoot()Creates a root for this server. Can be overridden to create another root.

 二、CoapServer服务运行分析

        在了解了上述的CoapServer的相关接口和类的设计和实现后,我们可以来跟踪调试一下CoapServer的实际服务运行过程。它的生命周期运行是一个怎么样的过程,通过下面的章节来进行讲解。

1、CoapServer对象实例化

        在之前的代码中,我们对CoapServer对象进行了创建,来看一下关键代码。从使用者的角度来看,这是最简单不过的一个Java对象实例的创建,并没有稀奇。然而我们要深入到其类的内部实现,明确了解在创建CoapServer的过程中调用了什么逻辑。这里我们将结合时序图的方式进行讲解。


CoapServer server = new CoapServer();// 主机为localhost 端口为默认端口5683

 从上面的时序图可以看到,在CoaServer的内部,在创建其实例的时候。其实做了很多的业务调用,大致可以分为18个步骤,下面结合代码进行介绍:

1.1 调用构造方法

/*** Constructs a server with the specified configuration that listens to the* specified ports after method {@link #start()} is called.** @param config the configuration, if <code>null</code> the configuration returned by* {@link NetworkConfig#getStandard()} is used.* @param ports the ports to bind to*/public CoapServer(final NetworkConfig config, final int... ports) {// global configuration that is passed down (can be observed for changes)if (config != null) {this.config = config;} else {this.config = NetworkConfig.getStandard();}// resourcesthis.root = createRoot();this.deliverer = new ServerMessageDeliverer(root);CoapResource wellKnown = new CoapResource(".well-known");wellKnown.setVisible(false);wellKnown.add(new DiscoveryResource(root));root.add(wellKnown);// endpointsthis.endpoints = new ArrayList<>();// sets the central thread pool for the protocol stage over all endpointsthis.executor = Executors.newScheduledThreadPool(//this.config.getInt(NetworkConfig.Keys.PROTOCOL_STAGE_THREAD_COUNT), //new NamedThreadFactory("CoapServer#")); //$NON-NLS-1$// create endpoint for each portfor (int port : ports) {CoapEndpoint.CoapEndpointBuilder builder = new CoapEndpoint.CoapEndpointBuilder();builder.setPort(port);builder.setNetworkConfig(config);addEndpoint(builder.build());}}

1.2 生成全局配置

        在这里,系统会根据传入的参数进行全局配置,如果不传入config,则自动根据默认参数进行系统配置。否则根据传入参数进行配置。在系统分析时可以看到,如果系统第一次运行,配置文件是不存在的,因此在不存在的时候,会将默认配置写入到工程下面的配置文件中。

public static NetworkConfig getStandard() {synchronized (NetworkConfig.class) {if (standard == null)createStandardWithFile(new File(DEFAULT_FILE_NAME));}return standard;}public static NetworkConfig createWithFile(final File file, final String header, final NetworkConfigDefaultHandler customHandler) {NetworkConfig standard = new NetworkConfig();if (customHandler != null) {customHandler.applyDefaults(standard);}if (file.exists()) {standard.load(file);} else {standard.store(file, header);}return standard;}public void store(File file, String header) {if (file == null) {throw new NullPointerException("file must not be null");} else {try (FileWriter writer = new FileWriter(file)) {properties.store(writer, header);} catch (IOException e) {LOGGER.warn("cannot write properties to file {}: {}",new Object[] { file.getAbsolutePath(), e.getMessage() });}}}

1.3 创建Resource对象

        通过Server对象本身提供的createRoot()方法进行Resource对象的创建。

1.4-1.8、配置消息传递器、添加CoapResource

CoapResource wellKnown = new CoapResource(".well-known");
wellKnown.setVisible(false);
wellKnown.add(new DiscoveryResource(root));
root.add(wellKnown);
this.endpoints = new ArrayList<>();

1.9-1.12 创建线程池

        这里很重要,通过创建一个容量为16的线程池来进行服务对象的处理。

// sets the central thread pool for the protocol stage over all endpoints
this.executor=Executors.newScheduledThreadPool(this.config.getInt(NetworkConfig.Keys.PROTOCOL_STAGE_THREAD_COUNT), new NamedThreadFactory("CoapServer#")); //$NON-NLS-1$

1.3-1.7 端口绑定、服务配置

        在这里通过for循环的方式,将各个需要处理的端口与应用程序进行深度绑定,配置对应的服务。到此,CoapServer对象已经完成了初始创建。

2、添加处理器

        在创建好了CoapServer对象后,我们使用server.add(new CoapResource())进行服务的绑定,这里的CoapResource其实就是类似于我们常见的Controller类或者servlet。

3、服务启动

下面来看下CoapServer的启动过程,它的启动主要是调用start方法。时序图调用如下图所示:

 1.1-1.5、绑定端口及相关服务

if (endpoints.isEmpty()) {// servers should bind to the configured port (while clients should use an ephemeral port through the default endpoint)int port = config.getInt(NetworkConfig.Keys.COAP_PORT);LOGGER.info("no endpoints have been defined for server, setting up server endpoint on default port {}", port);CoapEndpoint.CoapEndpointBuilder builder = new CoapEndpoint.CoapEndpointBuilder();builder.setPort(port);builder.setNetworkConfig(config);addEndpoint(builder.build());}

1.7-1.8 循环启动EndPoint

int started = 0;for (Endpoint ep : endpoints) {try {ep.start();// only reached on success++started;} catch (IOException e) {LOGGER.error("cannot start server endpoint [{}]", ep.getAddress(), e);}}

每个EndPoint会设置自己的启动方法,

@Overridepublic synchronized void start() throws IOException {if (started) {LOGGER.debug("Endpoint at {} is already started", getUri());return;}if (!this.coapstack.hasDeliverer()) {setMessageDeliverer(new ClientMessageDeliverer());}if (this.executor == null) {setExecutor(Executors.newSingleThreadScheduledExecutor(new DaemonThreadFactory("CoapEndpoint-" + connector + '#'))); addObserver(new EndpointObserver() {@Overridepublic void started(final Endpoint endpoint) {// do nothing}@Overridepublic void stopped(final Endpoint endpoint) {// do nothing}@Overridepublic void destroyed(final Endpoint endpoint) {executor.shutdown();}});}try {started = true;matcher.start();connector.start();for (EndpointObserver obs : observers) {obs.started(this);}startExecutor();} catch (IOException e) {stop();throw e;}}

4、服务运行

        在经过了上述的实例对象创建、请求资源绑定、服务启动三个环节,一个可用的CoapServer才算是真正完成。运行终端代码可以看到服务已经正常启动。

         由于篇幅有限,类里面还有其他重要的方法不能逐一讲解,感兴趣的各位,可以在工作中认真分析源代码,真正掌握其核心逻辑,做到胸有成竹。

总结

        以上就是本文的主要内容,本文将采用OOP的设计方法对Californium中Server的实现和启动进行源码级的分析,让读者对Coap的实现有进一步的了解,帮助掌握其设计和实现细节。行文仓促,难免有遗漏和不当之处,欢迎各位朋友在评论区批评指正。

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

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

相关文章

文献研读|Prompt窃取与保护综述

本文介绍与「Prompt窃取与保护」相关的几篇工作。 目录 1. Prompt Stealing Attacks Against Text-to-Image Generation Models&#xff08;PromptStealer&#xff09;2. Hard Prompts Made Easy: Gradient-Based Discrete Optimization for Prompt Tuning and Discovery&#…

说说 Spring Boot 实现接口幂等性有哪几种方案?

一、什么是幂等性 幂等是一个数学与计算机学概念&#xff0c;在数学中某一元运算为幂等时&#xff0c;其作用在任一元素两次后会和其作用一次的结果相同。 在计算机中编程中&#xff0c;一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数或幂等…

人工智能_机器学习076_Kmeans聚类算法_体验_亚洲国家队自动划分类别---人工智能工作笔记0116

我们开始来看聚类算法 可以看到,聚类算法,其实就是发现事物之间的,潜在的关联,把 有关联的数据分为一类 我们先启动jupyter notebook,然后 我们看到这里我们需要两个测试文件 AsiaFootball.txt里面记录了,3年的,亚洲足球队的成绩

【微服务核心】Spring Boot

Spring Boot 文章目录 Spring Boot1. 简介2. 开发步骤3. 配置文件4. 整合 Spring MVC 功能5. 整合 Druid 和 Mybatis6. 使用声明式事务7. AOP整合配置8. SpringBoot项目打包和运行 1. 简介 SpringBoot&#xff0c;开箱即用&#xff0c;设置合理的默认值&#xff0c;同时也可以…

ActiveMQ漏洞合集

目录 介绍CVE-2015-5254&#xff1a;Apache ActiveMQ任意代码执行漏洞漏洞介绍 & 环境准备漏洞发现Nuclei❌Vulmap✅漏洞验证漏洞利用 CVE-2016-3088&#xff1a;Apache ActiveMQ Fileserver远程代码执行漏洞漏洞发现Nuclei✅Vulmap✅MSF✅第三方工具1&#xff08;漏洞探测…

机器学习硬件十年:性能变迁与趋势

本文分析了机器学习硬件性能的最新趋势&#xff0c;重点关注不同GPU和加速器的计算性能、内存、互连带宽、性价比和能效等指标。这篇分析旨在提供关于ML硬件能力及其瓶颈的全面视图。本文作者来自调研机构Epoch&#xff0c;致力于研究AI发展轨迹与治理的关键问题和趋势。 &…

Typora Mac激活

首先去官网选择mac版本下载安装 typora下载 然后打开typora包内容找到 /Applications/Typora.app/Contents/Resources/TypeMark/page-dist 找到/static/js/Licen..如下图 编辑器打开上面文件夹 输入 hasActivated"true"e.hasActivated 进行搜索 将它改为 hasA…

算法基础之数字三角形

数字三角形 核心思想&#xff1a;线性dp 集合的定义为 f[i][j] –> 到i j点的最大距离 从下往上传值 父节点f[i][j] max(f[i1][j] , f[i1][j1]) w[i][j] 初始化最后一层 f w #include <bits/stdc.h>using namespace std;const int N 510;int w[N][N],f[N][…

12.26

key_it.c #include"key_it.h" void led_init() {// 设置GPIOE/GPIOF时钟使能RCC->MP_AHB4ENSETR | (0x3 << 4);// 设置PE10/PE8/PF10为输出模式GPIOE->MODER & (~(0x3 << 20));GPIOE->MODER | (0x1 << 20);GPIOE->MODER & (~…

Java之遍历树状菜单

&#x1f607;作者介绍&#xff1a;一个有梦想、有理想、有目标的&#xff0c;且渴望能够学有所成的追梦人。 &#x1f386;学习格言&#xff1a;不读书的人,思想就会停止。——狄德罗 ⛪️个人主页&#xff1a;进入博主主页 &#x1f5fc;专栏系列&#xff1a;无 &#x1f33c…

【小白专用】Apache下禁止显示网站目录结构的方法 更新23.12.25

给我一个网站地址&#xff0c;我点开后显示的是目录格式&#xff0c;把网站的目录结构全部显示出来了 这个显示结果不正确&#xff0c;不应该让用户看到我们的目录结构 配置文件的问题,apache配置文件里有一项可以禁止显示网站目录的配置项&#xff0c;禁止掉就好了 在apache…

alertmanage调用企业微信告警(k8s内部署)

一、前言 alertmanage调用企业微信应用告警会比直接使用钉钉告警更麻烦一点&#xff0c;调用企业微信应用告警需要在应用内配置企业可信ip&#xff0c;不然调用企业微信接口就会报错&#xff0c;提示ip地址有风险 二、部署 先自行创建企业微信&#xff0c;再使用管理后台创建应…

【GitHub精选项目】抖音/ TikTok 视频下载:TikTokDownloader 操作指南

前言 本文为大家带来的是 JoeanAmier 开发的 TikTokDownloader 项目&#xff0c;这是一个高效的下载 抖音/ TikTok 视频的开源工具。特别适合用户们保存他们喜欢的视频或分享给其他人。 TikTokDownloader 是一个专门设计用于下载 TikTok 视频的工具&#xff0c;旨在为用户提供一…

阿里云自建官方Docker仓库镜像提交拉取方法

文章目录 发布镜像到DockerHub发布镜像到自建Docker仓库(Harbor)修改配置文件在Linux服务器中登录Docker打TAGPUSH提交镜像PULL拉取镜像 发布镜像到阿里云容器服务在Linux服务器中登录DockerPUSH提交镜像PULL拉取镜像 发布镜像到DockerHub 本地我们镜像命名可能会不规范&#…

设计模式-单例模式(结合JVM基础知识)

1.定义介绍 所谓单例模式&#xff0c;是指在程序运行时&#xff0c;整个JVM中只有一个该类的实例对象 2. 单例模式的优点 复用性高&#xff0c;节省内存资源。类的加载、连接、初始化、使用都要占用虚拟机内存空间&#xff0c;因此&#xff0c;频繁创建对象会造成资源浪费&a…

从企业级负载均衡到云原生,深入解读F5

上世纪九十年代&#xff0c;Internet快速发展催生了大量在线网站&#xff0c;Web访问量迅速提升。在互联网泡沫破灭前&#xff0c;这个领域基本是围绕如何对Web网站进行负载均衡与优化。从1997年F5发布了BIG-IP&#xff0c;到快速地形成完整ADC产品线&#xff0c;企业级负载均衡…

家校互通小程序实战开发02首页搭建

目录 1 创建应用2 搭建首页总结 我们上一篇介绍了家校互通小程序的需求&#xff0c;创建了对应的数据源。有了这个基础的分析之后&#xff0c;我们就可以进入到开发阶段了。开发小程序&#xff0c;先需要创建应用。 1 创建应用 登录控制台&#xff0c;点击创建应用&#xff0c…

工具系列:TimeGPT_(2)使用外生变量时间序列预测

文章目录 TimeGPT使用外生变量时间序列预测导入相关工具包预测欧美国家次日电力价格案例 TimeGPT使用外生变量时间序列预测 外生变量在时间序列预测中非常重要&#xff0c;因为它们提供了可能影响预测的额外信息。这些变量可以包括假日标记、营销支出、天气数据或与你正在预测…

CentOS安装Docker

目录 一、前置条件 二、安装Docker 安装方式 配置镜像仓库 执行安装 启动Docker 检查Docker是否可以正常运行 三、卸载Docker 卸载Docker核心组件 清理Docker相关资源 参考文档 一、前置条件 安装 Docker 之前&#xff0c;需要先准备 CentOS 环境 目前支持 CentOS…

VScode跑通Remix.js官方的contact程序开发过程

目录 1 引言 2 安装并跑起来 3 设置根路由 4 用links来添加风格资源 ​5 联系人路由的UI 6 添加联系人的UI组件 7 嵌套路由和出口 8 类型推理 9 Loader里的URL参数 10 验证参数并抛出响应 书接上回&#xff0c;我们已经跑通了remix的quick start项目&#xff0c;接下…