基于观察者模式的COAP课程教学与实验设计
2019-02-07张笑非段先华王长宝王艳
张笑非 段先华 王长宝 王艳
摘要:CoAP是M2M的核心技术之一,其观察者模式是一种软件设计模式。IETF RFC 7641定义的CoAP资源观察機制正是基于该模式,是CoAP教学和实验内容的重要组成部分。将CoAP中资源观察消息的传递过程与通知的传输控制、时效性模型结合进行课程教学内容设计,通过Eclipse开源项目Californium中提供的API设计相应实验,并利用JUnit框架设计CoAP资源观察的测试用例,测试结果验证了相应资源观察过程。将该设计运用到实际教学活动中,学生对CoAP的内涵理解及编程能力都有提高。
关键词:观察者模式;资源观察通知;传输控制;时效性模型;受限节点/网络
DOI:10.11907/rjdk.191316
中图分类号:G434 文献标识码:A 文章编号:1672-7800(2019)012-0199-05
0引言
CoAP是一种应用于受限节点,网络的应用层传输协议…,是物联网等相关专业教学的重要内容。RFC 7641中定义的CoAP资源观察机制就是基于观察者模式,该模式是GoF提出的23种软件设计模型之一,被称为观察者(Observer)的组件向其感兴趣的、称为被察者(subjeet)的服务端进行注册。此后,被察者状态变化信息都会主动通知在册的观察者。观察者模式作为一种设计模型,涉及软件、物联网、通信等领域应用,文献[4]提出了基于并行的观察者改进模式,以满足实时系统中大量数据的更新;文献[5]提出了基于观察者的动态演化模型,以提高软件系统的动态演化效率;文献[6]提出了基于观察者模式的复杂实时系统验证方法;文献[7]采用了观察者模式对气象卫星数据接收与预处理调度机制进行研究;文献[8]将该模式应用于电信管理网络;文献[9]通过对观察者模式改进并应用到分布式开发中;文献[10]给出了在Observer模式中应用c#中的委托方法;文献[11]一[12]将该模式应用于软件设计;文献[13]利用CoAP对已存在的软件架构进行改进。同样,研究如何将CoAP及观察者模式应用到物联网环境,以及研究观察者模式在CoAP课程中的教学和实验设计,对于提高学生实际应用观察者模式能力有重要意义。
1COAP教学设计
本文利用文献[14]-[15]中基于RFC文档进行教学的设计思路,以RFC 7641中的CoAP资源观察机制为基础,讲解受限节点/网络环境中CoAP资源观察通知的传输方法与时效性模型。基于这两个机制设计教学案例,帮助学生理解在受限节点,网络环境和常规互联网环境下,由于需求差异导致CoAP/UDP与HTTPfFCP在消息传递及传输控制上的区别。
1.1教学内容设计
1.1.1资源观察通知传输方法
CoAP资源观察关系建立后,资源更新通知主要依靠扮演被察者的CoAP服务端进行传输控制。传输控制包含两个主要要素:①消息传输的可靠机制,包括需确认(cON,confirmable)或免确认(NON,non-confirmable)传输;②消息传输的控制机制,包括停止等待(stop-and-wait)或实时方式。如表l所示,这两个要素可以组合出3种资源观察通知传输方法,其中免确认的CoAP消息与停止等待方式无法结合。
若关注被察者与观察者对于某资源状态的同步效率,则实时方式通知更加适合。图l中示例需确认实时资源观察通知,被察资源(interested resource)第二次发生变化时,将该变化observe(2)以MID(消息标识符)为3100的确认消息发送给观察者。在未收到相应的ACK消息时,被察资源发生第3次变化observe(3),于是就直接将该变化再次发送出去。由于需确认消息在未收到相应ACK消息时其MID不会增加,所以携带observe(2)与observe(3)的消息MID是一样的。实时方式下需确认通知与免确认通知区别在于,前者中的被察者会收到重复的ACK消息。
类似地,图2中示例的免确认实时资源观察通知,被观察者资源第二次发生变化时,将该变化observe(2)以MID为3100免确认消息发送给观察者。被察资源发生了第三次变化observe(3)时,也直接将该变化再次发送出去,并没有考虑频繁的通知可能会造成受限网络的拥塞。另外,由于是免确认方式,所以两次消息的MID产生了变化。
突发性资源状态变化会产生过多通知,这对于受限网络的承载能力和受限节点处理能力都是极大挑战。图3中的示例需确认资源观察通知,被察者在MID为3100的消息中将资源变化observe(2)通知给观察者,虽然之后资源状态经历了observe(3)、observe(4)、observe(5)的变化,但未直接生成相应通知。直到接收到相应的ACK消息后,被察者才将最新的状态observe(5)通过MID为3101的需确认消息通知给观察者。由于承载observe(2)的需确认消息已经被确认,所以承载observe(5)的需确认消息的MID数值增加了1。
1.1.2资源观察通知时效性模型
通过表1可知,免确认的消息只能与实时方式结合,当被察资源异常频变时,必然不适合受限结点,网络场景。教学设计中针对这一问题在RFC 7641中对资源观察通知的时效性模型进行设计。时效性模型一方面会省略被察资源的一些中间状态,但又不会导致两端信息同步收敛过于缓慢,时效性模型只能满足最终一致性(eventual con-sistency),即被察者状态稳定时,观察者终究会获得这个最新的状态信息。
时效性模型充分考虑到受限节点,网络限制。为保证资源观察两端信息同步效率可接受,引人Max-Age(资源状态时效期)这一参数,即被察者相邻两次通知的发送时间间隔不能超过Max-Age。如图4所示,发送完MID为3100的通知后Max-Age便开始计时。在未过期前发送了MID为3101的通知,中间的资源状态变化3和4都被跳过,即使这个期间被察资源没有发生任何变化,被察者也会在Max-Age超时前发送一次携带observe(2)的通知,告知观察者被察资源状态无变化。时效性模型同样可以传输需确认的消息,以及结合实时通知传输。
1.2教学案例设计
1.2.1简单资源观察过程
CoAP资源观察中的观察者,首先会通过一个携带ob-serve选項的GET消息与被察者建立资源观察关系。由于该请求消息是GET操作,所以被察者会先返回一个ob-serve(0)作为对GET操作的返回结果,后续状态变化通知会通过observe(i),i=1,2,3,…返回。
图5是CoAP观察者向被察者发起一个MID为7001的免确认GET操作,对资源/obs进行观察。被察者一方面基于token等参数将该观察者加入注册列表,另一方面要对GET操作进行处理,于是向观察者返回了一个MID为3098的免确认消息,消息中携带资源/obs的当前信息ob-serve(0)。观察者在接收到该消息后,一方面获得了当前被察者资源lobs的状态,同时也确认了与被察者观察关系的建立。之后,被察者资源/obs发生3次变化,即observe(1)、observe(2)和observe(3),并被封装成独立的CoAP消息,即MID分别以3099、3100、3101的通知返还给观察者。其中MID为3100的消息需确认,目的是被察者测试一下与观察者的连通性,若不连通则需要将该观察者从注册列表里删除,以撤销相应的观察关系。最后,观察者通过向被察者发送一个RST,即复位消息用来撤销观察关系,被察者在收到该消息后,会根据token等参数将该观察者从其注册列表中删除。
1.2.2多因素驱动通知生成
被察者何时生成新的通知并向观察者发送有多种驱动因素。就目前RFC 7252和RFC 7641中的机制,这些因素包括GET操作、ACK确认、ACK超时(ACK_TIMEOUT)、Max-Age、资源状态更新等5种。图5的案例包含了GET操作、ACK确认及资源状态更新这3种因素。为了包含ACK_TIMEOUT因素,通过丢弃所有需确认的通知而导致相应消息在ACK_TIMEOUT规定的时间内没有被确认而重新发送。除此以外,该案例设计还考虑了时效性模型中的Max-Age,介绍如何触发通知的生成与发送。
如图6所示,被察者一共生成并发送6次状态信息。其中通知observe(0)是由GET操作触发的,observe(1)、ob-serve(2)、observe(3)的第一次是由资源状态变化触发的,observe(1)和observe(3)的第二次是由ACK_TIMEOUT触发的。这个案例的一个设计重点在于区分同属超时机制的ACK_TIMEOUT和Max-Age究竟哪一个在发挥作用。注意MID为39551的通知都是需确认的,如果是免确认的就不会出现ACK_TIMEOUT触发的情况。
RFC 7252中需确认消息的超时机制使用二进制指数退避算法,参数ACK_TIMEOUT缺省是2秒、ACK_RAN-DOM_FACTOR缺省是1.5、MAX_RETRANSMIT缺省是4次,即每两次重传之间的时间间隙分别是3、6、12、24秒。同一个MID需确认的消息从第一次尝试发送到最后一次尝试发送的间隔称为MAX_TRANSMIT_SPAN,缺省值为45秒。而RFC 7641中时效性模型定义的Max-Age缺省值是60秒。因此,Max-Age还未触发时,该消息重传次数就已经达到最大次数。考虑到案例中MID为3955l的通知有两次是状态更新触发的,因此MAX_TRANSMIT_SPAN的实际值小于45秒。被察者唯一通过Max-Age触发通知的可能就是MAX_TRANSMIT_WAIT不小于60秒,否则被察者就会将观察者从注册列表中删除。
Max-Age不仅可在被察者端触发通知的生成,也可在观察者端触发GET操作,间接向被察者查询资源状态。图6中,观察者在接收到MID为7001的通知时,其中的ob-serve选项可以携带被察者设置的Max-Age值,以告知资源时效性的最大间隔。也就是说,观察者在此刻开始的Max-Age时间间隔内,认为observe(0)是具有时效性的。若超过这个时间间隔,说明observe(0)已经无效,考虑到受限网络可能存在拥塞,可以通过携带observe选项的GET操作重新与被察者建立观察关系。
2COAP实验设计
本文采用Eclipse开源项目Californium E171作为基于观察者模式的CoAP实验环境,该开源项目提供了CoAP所有特性所需的后台服务,能够很好地与IoT设备进行交互。实验设计利用文献[18]中将JUnit应用到课程教学中的方法,通过在Californium中编写JUnit测试单元测试并验证每个实验设计。
2.1案例测试框架设计
除了之前设计的两个教学案例,CoAP教学还设计了Max-Age动态调整的资源观察过程、资源观察通知块级传输过程等案例。因此,为了提高测试代码重用性,在实验设计上采用文献[19]提到的案例分解与重构思路,采用JUnit4的标注机制定义案例的通用模块和独立模块。如图7所示,用@BeforeClass定义CoAP网络参数初始化函数start(),用@Before定义CoAP观察者和被察者的创建函数setupServer(),用@After定义CoAP观察者和被察者的销毁函数shutdownServer(),用@Test分别定义资源观察过程函数simpleResourcesObserving()、muhipleFactorsDrivenNo-tification()、observingWithDynamicMaxage()、observingWith-BlockwiseTransfer()等。
2.2测试通用模块设计
锁步(Lockstep)是一种容错技术,通过显式指令完成同步控制。实验设计将CoAP观察者和被察者分别运行在锁步模式和正常模式,利用锁步模式控制观察者的每一次消息发送和接收,从而重现教学案例中设计的资源观察过程。因此,首先定义测试用例的静态初始化函数start(),在其中设定CoAP被察者的网络参数初始值:
2.3测试独立模块设计
实验设计中,工作在锁步模式的client通过函数send-Request和expectResponse分别完成消息的发送和接收。此外,测试用例通过函数testObsResources.change()实现被察资源/obs的更新,通过函数serverInterceptor.log()模拟CoAP消息的丢失。以案例“多因素驱动的通知生成”为例,为了完成图6中的资源观察过程,通过函数generater-andomPayload为CoAP观察者生成指定长度的GET操作载荷。另外,CoAP观察者还要创建token作为在被察者端注册的主要参数及path指定被察资源路径。
2.4测试结果
将通用模块和该案例的独立模块组合作为JUnit单元测试,图8中的运行结果验证了案例“多因素驱动的通知生成”在教学设计上的资源观察过程。
3结语
观察者模式应用于物联网、通信、软件等技术中,基于它进行课程内容讲解可帮助学生触类旁通,提高学习效率和再创造能力。本文结合RFC标准和开源项目,对CoAP课程的教学和实验内容进行设计,在理论内容上紧跟业界发展趋势,在实践环节上具有应用价值。这种结合业界标准和开源项目进行课程设计的方法,同样可以应用到相关专业其它课程中,对提高课程内容的内涵和市场接纳度具有积极意义。