具体实施方式
下面对本发明的技术方案做进一步的详细描述。
一、面向资源REST式架构
无论对于协议实现者还是协议的客户端,使用REST式的协议设计更有利于他们整体把握业务流程和协议的语义。在REST风格中,资源的访问统一使用四种操作——Create创建、Retrieve查询、Update修改、Delete删除,此处沿用。在本方法中对资源进行访问时,使用/category/sub-category/uuid的资源路径进行,这是对资源的自然分类,很好理解。需注意,资源不仅局限于对应设备上的硬件单元,它也对应业务单元(如远程音视频输入、远程音视频输出、事件触发时响应的预案等)。作为资源的全局唯一标识,UUID(Universal Unique Identifier,全局唯一标识符)与资源存在一一对应关系,而不是资源路径。这是因为,一个资源可能具有多个角色,这样我们可以从任意一个资源路径对其进行访问,而UUID则是决定资源的唯一标识。
在REST式风格下,设备的各个功能单元作为资源存在,而资源本身是抽象的,我们要观察或改造资源都需要对资源进行描述或表征。表征的方法有很多,按照数据格式可分为二进制描述和基于文本的描述两类。实践已经证明基于文本的描述在语义的精确性(大小端问题)、容错性、向前向后兼容性、开发者友好性(XML)方面都远优于二进制描述,唯一的不足只是具体实现必须在运行时对文本描述进行解析,但这对于越来越强大的硬件来说不存在问题。因此,我们选择使用XML作为主要描述方式,所有的实现都必须支持XML方式,其他可选方式为JSON,以便与AJAX(异步JavaScript与XML,Asynchronous JavaScript and XML,该技术用于实现快速响应Web应用程序)技术联合使用,提供快速响应的RIA(富互联网应用,Rich Internet Application,它是具有桌面应用特性的Web应用程序,这类应用通常借助AJAX或Adobe Flash等技术,将用户界面相关的计算、数据的初步验证计算等部署在浏览器端,而只与服务器进行必要的数据交互,从而具有远高于传统Web应用的响应速度)。
二、抽象的请求——响应模型(与承载协议无关)
这种音视频服务配置的方法,其符合请求—响应模型,请求消息体包括:(a1)资源路径,以UNIX文件系统路径的方式表达各个资源的层次结构;(a2)资源访问方式,包括查询、修改、创建、删除四种;响应消息体包括:(r1)响应返回值,包括“OK”、“Bad Request”、“Unauthorized”、“Forbidden”、“Not Found”、“Method Not Allowed”、“Internal Server Error”、“Service Unavailable”,每种资源还可以加入专有的返回值。
根据操作的不同,请求消息体还包括:(a3)在创建、修改资源时对资源的表征可选择XML表征或JSON表征,其中XML表征可选用XML Schema或RelaxNG对其进行验证,在对资源进行修改或查询时需要包含对资源的新的表征;对应地,响应消息体包括:(r2)在创建新资源时新资源对应的资源路径;在对资源进行查询请求时返回资源的表征。
该方法通用于下层承载协议,并可与下层承载协议结合为一种实体协议。
本方法只是对业务需求的一种抽象:业务实践中需要创建、访问、修改、删除各种资源,访问资源时用资源路径指明访问的是哪个资源,指明访问方法,以及得到或修改资源的表征。但对于其具体形式,本方法未作强制规定,而是指明了用HTTP和D-Bus作为信息载体的两种实体协议。在方法实现与二次开发中,我们都是应用实体协议来进行信息交换,但本方法是对信息交换背后的实质进行描述。这意味着:首先,本方法需要与承载协议组成实体协议才能具体应用,如HTTP或D-Bus;其次,本方法可以应用于任意一种承载协议,只要其保证准确传输,同时能将消息体的各部分区分开。
三、基于HTTP的实体协议——工作于互联网环境
例如,作为承载协议的HTTP与本方法结合为一种实体协议,具体实现方法包括以下步骤:
(H1)将资源路径映射为HTTP URI的方法:对于支持虚拟主机(Virtual Host)特性的HTTP服务器,我们保持一个资源路径的字面值不变,并将其映射到虚拟主机hbservice下;否则,我们将其加上/hbservice前缀,并映射到默认主机下;
(H2)将资源访问方式映射为HTTP Method的方法:对资源的创建访问映射为HTTP的POST Method;对资源的查询访问映射为HTTP的GET Method;对资源的修改访问映射为HTTP的PUT Method;对资源的删除访问映射为HTTP的DELETE Method;(此步骤只适用于资源访问请求消息,因为响应消息中不存在访问方法信息)
(H3)将资源表征映射为HTTP消息体的方法:为了适应国际化、多语言支持等需求,资源表征在HTTP消息体中使用UTF-8编码,具体的映射方法为通过HTTP消息头中的字段Content-Type规定使用哪种格式的表征:(t1)XML格式使用Content-Type:text/xml;charset=utf-8;(t2)JSON格式使用Content-Type:application/json;charset=utf-8;通过HTTP消息头中的字段Content-Length规定表征数据的大小;Content-Type字段和Content-Length字段是HTTP标准中规定的消息头字段,因此承载协议的实现必须符合HTTP标准;
(H4)通过HTTP协商,选择返回XML或JSON表示的方法:此处的协商规则以HTTP标准12.1节Server-Driven Negotiation为基础,并略加限制,具体规则如下:(n1)如不加任何限制(即HTTP请求消息头中没有Accept字段),则客户端与服务器默认双方使用XML格式进行数据交互;(n2)如加限制必须由客户端发起协商,为此客户端需要在HTTP请求消息中加入请求头Accept字段,格式为Accept:mt1;q=q1,mt2;q=q2,(其中mt1、mt2代表资源的表征格式,可以在text/xml或application/json中进行选择;q1、q2值为0.0到1.0之间的十进制浮点数,且q1大于q2,表示对某种表征的偏好优先级);如客户端仅支持某一种特定格式,则相应的形式为Accept:mt,mt为text/xml或application/json;(n3)服务器根据客户端提供的信息,从所有支持的表征类型中选取客户端最为偏好的形式;如果服务器不支持客户端请求的表征类型,则返回错误信息“415Unsupported Media Type”。
四、基于D-Bus的实体协议——实用的系统集成模型
本方法最理想的承载协议为HTTP,但考虑到设备处理能力,以及组件集成能力,我们需要D-Bus承载协议来帮助在资源受限平台上开发实现。按照D-Bus规范,服务对象为服务进程所拥有。服务进程在接入D-Bus消息总线后需要申请一个公共名(well-known name),本协议范畴内的所有通信都由公共名定位服务进程。服务进程负责维护资源,并在D-Bus总线上为每个资源(服务对象)申请对象路径。。拥有多种角色(即隶属于多个类、子类)的资源,必须要为每个资源路径申请唯一的D-Bus对象路径(Object Path)。D-Bus总线上的对象分两类:管理器(Manager)与实体(Entity)。实体对应位于资源路径的叶子节点的资源,负责控制设备完成具体的业务功能;管理器对应位于非叶子节点的资源,负责对实体的管理。在对资源进行访问时,需要首先用D-Bus公共名定位服务进程,以确定请求消息的目的地;同时需要用资源的D-Bus对象路径定位具体资源,用D-Bus接口(Interface)指明访问资源的哪个功能组,以及用D-Bus方法(Method)指明访问资源的哪个具体功能。因此,用D-Bus协议实现本协议就涉及以下方面:(1)如何确定D-Bus公共名(2)如何确定D-Bus对象路径(3)如何确定D-Bus接口和方法。具体的实现方法如下:
1.HTTP服务器收到客户端的请求消息,基于HTTP的实体消息与本方法消息存在一一映射关系;
2.HTTP服务器解析HTTP消息得到本方法消息;
3.HTTP服务器将本方法消息一一映射为D-Bus消息,并发送到D-Bus总线上相应的对象(服务);
4.D-Bus服务执行相应的动作,并通过D-Bus总线将响应结果返回给HTTP服务器;
5.HTTP服务器解析D-Bus消息得到本协议响应消息;
6.HTTP服务器将本方法响应消息一一映射为HTTP响应消息并发送给客户端。
即,作为承载协议的D-Bus消息协议与本方法结合为一种实体协议,具体实现方法包括以下步骤:
(D1)将资源路径映射为D-Bus对象路径的方法:在资源路径前加上前缀/com/hbgk组成D-Bus对象路径;
(D2)将访问方式映射为D-Bus接口与方法的方法:在构成总线名(Bus Name)时,使用D-Bus对象路径的前三级,去掉首位的“/”,将其他两个“/”改为“.”(即总线名为com.hbgk.category),通过总线名与对象路径来定位D-Bus对象;在构成D-Bus接口(interface)时,使用对象路径的直接父节点,并进行总线名相同的操作(即接口为com.hbgk.category.sub-category,若资源不存在子类型,则直接使用com.hbgk.category);对资源访问的方法按字面值映射到D-Bus对象,即D-Bus总线上的实体对象需要支持Create()、Retrieve()、Update()、Delete()四种方法调用;
(D3)将资源表征映射为D-Bus方法调用的参数及返回值的方法:(1)自行定义出口参数Result的具体类型,出口参数Result用来返回操作成功与否,以及相应的错误信息;(2)Create()方法的出口参数ObjPath,用于返回被创建对象的对象路径,不能在创建时给定UUID;Create()方法的入口参数Representation,用来传入新建对象初始状态的描述;Create()方法的入口参数RepType,用来指定初始状态描述使用XML或JSON格式(3)Retrieve()方法的出口参数Representation,用来返回对象当前状态的描述;Retrieve()方法的入口参数RepType,用来指定使用XML或JSON格式并返回当前状态描述(4)Update()方法的入口参数Representation,用来传入对象新状态的描述;Update()方法的入口参数RepType,用来指定新状态描述使用XML或JSON格式(5)管理器实体不用支持Delete()方法,而实体对象必须支持Delete()方法。
运行于后端的D-Bus服务对象不仅能为HTTP服务器提供服务,也能为其他模块提供服务,事实上后端服务对象根本不关心也无从知晓发起请求的是HTTP服务器还是其他模块。这个特性对系统集成非常重要,此特性可以将系统的耦合度与重复开发的成本大幅降低。例如接入中兴力维、互信互通等电信级安防平台时,需要按平台厂商的协议接入,这时我们只需要加入相应的模块即可。附加模块的功能类比HTTP服务器,它只负责按平台商的接入协议发送、解析消息,生成、解析相应的D-Bus消息,即只需要作平台协议消息与D-Bus消息之间的映射。
五、其他实现细节
事务性动作往往按一定次序操作一组资源,它保证要么成功,要么回滚所有操作。由于本协议采用REST式架构,所以资源的访问粒度是一个资源而非一组,因此对事务性动作的支持不如RPC方式明确。从表面上看这是REST式架构的一个普遍问题,但实际上,我们可以通过定义各种事务执行器资源来解决此问题。本协议定义了一组事务执行器资源,以应对大多数用户需求,但对于某些特殊需求,仍然需要按单个资源的粒度进行操作来完成,这时就需要请求发起者来确保事务性语义。
本方法没有明确规定资源的访问限制,这是系统集成的责任。例如,我们可以在HTTP服务器上限制某些资源只能允许某些用户以某些方法访问。
以上所述,仅是本发明的较佳实施例,并非对本发明作任何形式上的限制,凡是依据本发明的技术实质对以上实施例所作的任何简单修改、等同变化与修饰,均仍属本发明技术方案的保护范围。