上文对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++实现。其类图如下:
主要包含的模块有:
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对象的指针。其类图如下:
6、关于NodeJS插件系统的几点补充
插件池对插件的异步回调实现
考虑到两个问题:
① 用户插件的异步调用的唤醒,在PhoneGap体系中是由PhoneGap中间层PluginManager通过是否创建线程的方式创造异步执行条件,即由PhoneGap中间层唤醒异步调用,这样的形式对用户插件自身需要实现回调的情况(如语音+接口)支持不够,因而NodeJS插件系统中将异步调用的唤醒权放给用户插件中以更好地兼容。
② 用户插件异步结果的返回,设计中考虑到两种方式,一个是当前的传递函数指针方式,另一个是windows消息机制(SendMessage、PostMessage),这两种方式皆可,但从实现难度上,指针传递方式较为方便,在跨平台情况下该方法也可以直接迁移。
多重回调、异步的安全性
NodeJS插件系统实质上是一套插件的插件集合,因而前端的一次接口调用要经过逐层向下直到调用用户插件的接口,而接口回调在每层中都可能唤醒,原则上接口回调的唤醒放在用户插件层,因而回调将经过逐层向上的调用过程。在这样涉及多层调用和回调的情况下,在实际开发中需谨慎运用,否则容易造成异常。
结果返回类型定义的标准程度
结果返回类型的标准化结构上参照PhoneGap,可以保证结果信息的完整性,但是在信息准确性上,还需根据NodeJS插件系统本身来进行细化调整最终达到相对完善的程度。