物联网协议Coap之Californium CoapServer解析

2023-12-27 12:52

本文主要是介绍物联网协议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的实现有进一步的了解,帮助掌握其设计和实现细节。行文仓促,难免有遗漏和不当之处,欢迎各位朋友在评论区批评指正。

这篇关于物联网协议Coap之Californium CoapServer解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/543202

相关文章

线上Java OOM问题定位与解决方案超详细解析

《线上JavaOOM问题定位与解决方案超详细解析》OOM是JVM抛出的错误,表示内存分配失败,:本文主要介绍线上JavaOOM问题定位与解决方案的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一、OOM问题核心认知1.1 OOM定义与技术定位1.2 OOM常见类型及技术特征二、OOM问题定位工具

深度解析Python中递归下降解析器的原理与实现

《深度解析Python中递归下降解析器的原理与实现》在编译器设计、配置文件处理和数据转换领域,递归下降解析器是最常用且最直观的解析技术,本文将详细介绍递归下降解析器的原理与实现,感兴趣的小伙伴可以跟随... 目录引言:解析器的核心价值一、递归下降解析器基础1.1 核心概念解析1.2 基本架构二、简单算术表达

HTTP 与 SpringBoot 参数提交与接收协议方式

《HTTP与SpringBoot参数提交与接收协议方式》HTTP参数提交方式包括URL查询、表单、JSON/XML、路径变量、头部、Cookie、GraphQL、WebSocket和SSE,依据... 目录HTTP 协议支持多种参数提交方式,主要取决于请求方法(Method)和内容类型(Content-Ty

深度解析Java @Serial 注解及常见错误案例

《深度解析Java@Serial注解及常见错误案例》Java14引入@Serial注解,用于编译时校验序列化成员,替代传统方式解决运行时错误,适用于Serializable类的方法/字段,需注意签... 目录Java @Serial 注解深度解析1. 注解本质2. 核心作用(1) 主要用途(2) 适用位置3

Java MCP 的鉴权深度解析

《JavaMCP的鉴权深度解析》文章介绍JavaMCP鉴权的实现方式,指出客户端可通过queryString、header或env传递鉴权信息,服务器端支持工具单独鉴权、过滤器集中鉴权及启动时鉴权... 目录一、MCP Client 侧(负责传递,比较简单)(1)常见的 mcpServers json 配置

从原理到实战解析Java Stream 的并行流性能优化

《从原理到实战解析JavaStream的并行流性能优化》本文给大家介绍JavaStream的并行流性能优化:从原理到实战的全攻略,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的... 目录一、并行流的核心原理与适用场景二、性能优化的核心策略1. 合理设置并行度:打破默认阈值2. 避免装箱

Maven中生命周期深度解析与实战指南

《Maven中生命周期深度解析与实战指南》这篇文章主要为大家详细介绍了Maven生命周期实战指南,包含核心概念、阶段详解、SpringBoot特化场景及企业级实践建议,希望对大家有一定的帮助... 目录一、Maven 生命周期哲学二、default生命周期核心阶段详解(高频使用)三、clean生命周期核心阶

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

Java Scanner类解析与实战教程

《JavaScanner类解析与实战教程》JavaScanner类(java.util包)是文本输入解析工具,支持基本类型和字符串读取,基于Readable接口与正则分隔符实现,适用于控制台、文件输... 目录一、核心设计与工作原理1.底层依赖2.解析机制A.核心逻辑基于分隔符(delimiter)和模式匹

Java+AI驱动实现PDF文件数据提取与解析

《Java+AI驱动实现PDF文件数据提取与解析》本文将和大家分享一套基于AI的体检报告智能评估方案,详细介绍从PDF上传、内容提取到AI分析、数据存储的全流程自动化实现方法,感兴趣的可以了解下... 目录一、核心流程:从上传到评估的完整链路二、第一步:解析 PDF,提取体检报告内容1. 引入依赖2. 封装