上文对PhoneGap的架构进行了简单介绍,本篇则具体对nodejs插件系统做介绍

二、NodeJS插件系统设计与实现

1、NodeJS概述:

                     NodeJS从实质上来说与PhoneGap具备的部分核心功能是一致的。

①   NodesJS平台的构建基于Chrome`sJavascript runtime,即对google v8引擎进行了封装,作为NodeJS的JavaScript解析引擎。

②   NodeJS支持插件(addon)模块,从而进行原生扩展。

2、NodeJS插件系统定义:

                     本质是将NodeJS的插件(addon)模块进行封装成一个插件池(PluginPool),通过PluginPool来管理自定义的插件,并提供标准化接口给NodeJS,最终暴露给js环境。

3、插件池(PluginPool)设计:

                     PluginPool的设计在架构上参照PhoneGap的插件系统架构进行了C++实现。其类图如下:

 

插件式架构 UML 插件系统设计_插件式架构 UML

 

 

 

主要包含的模块有:

PluginPool、NativePool类:

遵循NodeJS插件开发方法,完成插件池c++方法暴露到js环境的功能。

CPlugin类:

是所有插件的基类,在其中定义了插件的基本方法,但并不实现

 

CPluginManager类:

插件管理类,完成的功能包括:

①   根据xml文件动态加载插件及插件对象的初始化。

②   使用容器来保存加载的插件。

③   提供标准接口供插件池PluginPool调用,并根据调用参数匹配出目标插件(容器遍历),调用目标插件的目标方法。

④   不同于PhoneGap,这里将对插件接口的同步、异步调用的实现放到插件自身,PluginPool提供标准的回调函数供异步回调(同步则直接调用返回)。

ExecArgs类:

PhoneGap中使用JSON作为结果返回,在PluginPool则封装了ExecArgs类来实现JSON的功能,目标是将多个多种类型返回数据组合,标准化返回,其主要特点有:

①   支持多种类型数据入队:NodeJS支持对js传递参数类型的判断,根据判断结果将数据按类型入队;

②   支持数据类型判断:NodeJS支持向js环境返回数组,数组元素可以为不同数据类型。

PluginResult类:

结果返回类的标准化,定义了多种返回状态类型,主要返回内容以ExecArgs对象的形式体现。

CallBackManager模块:

负责所有向js环境回调函数的保存与调用,具体包括:

①   js回到函数保存:回调函数以V8的持久性数据类型Persistant<Function>保存在容器中,并生成自增长的callbackid用以唯一指定该回调函数。

②   提供一个面向所有插件的标准的回调函数,用于执行插件的回调,根据callbackid在容器中遍历查找匹配的js回调函数。

③   采用libuv库在C++环境中创建js运行环境,在js运行环境中执行匹配出的js回调函数

④   容器中保存的js回调函数是否释放将根据插件的回调传递参数来判定。

 

4、NodeJS插件系统通信过程描述

NodeJS插件系统的通信主要是从应用前端(javascript)到NodeJS中间层到插件池,再到用户插件(custom plugin)层,最后到原生API。

前端到NodeJS中间层通信:

①   由NodeJS的插件(addon)机制暴露接口给javascript环境直接调用

②   Google V8模块在C++环境下解析javascript方法来响应调用。

③   解析javascript得到js回调函数用来回调。

NodeJS中间层到插件池:

直接调用。

插件池到用户插件层:

依据C++的多态性,在运行时插件池动态调用匹配的目标插件的目标方法。

用户插件层直接调用原生API。

5、用户插件设计

用户插件为动态库,插件主体CNativePlugin继承自CPlugin并对类进行具体实现,动态库的唯一导出函数中创建并返回CNativePlugin对象的指针。其类图如下:

 

插件式架构 UML 插件系统设计_PhoneGap_02

6、关于NodeJS插件系统的几点补充

插件池对插件的异步回调实现

考虑到两个问题:

①   用户插件的异步调用的唤醒,在PhoneGap体系中是由PhoneGap中间层PluginManager通过是否创建线程的方式创造异步执行条件,即由PhoneGap中间层唤醒异步调用,这样的形式对用户插件自身需要实现回调的情况(如语音+接口)支持不够,因而NodeJS插件系统中将异步调用的唤醒权放给用户插件中以更好地兼容。

 

②   用户插件异步结果的返回,设计中考虑到两种方式,一个是当前的传递函数指针方式,另一个是windows消息机制(SendMessage、PostMessage),这两种方式皆可,但从实现难度上,指针传递方式较为方便,在跨平台情况下该方法也可以直接迁移。

 

多重回调、异步的安全性

NodeJS插件系统实质上是一套插件的插件集合,因而前端的一次接口调用要经过逐层向下直到调用用户插件的接口,而接口回调在每层中都可能唤醒,原则上接口回调的唤醒放在用户插件层,因而回调将经过逐层向上的调用过程。在这样涉及多层调用和回调的情况下,在实际开发中需谨慎运用,否则容易造成异常。

结果返回类型定义的标准程度

结果返回类型的标准化结构上参照PhoneGap,可以保证结果信息的完整性,但是在信息准确性上,还需根据NodeJS插件系统本身来进行细化调整最终达到相对完善的程度。