背景
由于Chrome开始抛弃NPAPI,导致我们原来用NPAPI来实现的插件,需要移植到NaCl(Native Client)。NaCl目前仅在Chrome浏览器中得到支持,具有本机运行C/C++程序,跨平台,安全沙箱,高性能等特点,比较适用于3D游戏,多媒体播放器,CAD建模等类型的插件开发。简介
还有一种取代NPAPI的技术叫Native Messaging,支持Chrome与本地程序的数据通信,但是不适用于我们的插件,有兴趣的自行了解一下(这里)。
Mac下的开发环境搭建
下载界面的下方,有安装的步骤,挺详细的。
如果出现下面错误,可以直接下载提示中的JSON文件,里面有各个平台和版本的SDK下载路径,根据需要下载即可(建议下载最新的稳定版本)。
2.Demo演示
使用终端,进入examples目录,然后执行 make命令编译所有Demo的代码。
接着将tools目录下的httpd.py文件拷贝到examples目录中,使用终端执行 ./httpd.py (需要安装Python2.7),便可以在浏览器中通过http://localhost:5103来访问Demo。(NaCl插件不能直接用本地的js来加载,所以要么是使用服务器的js来调用,要么是虚拟出服务器来执行本地的js)
3.创建自己的项目
这里使用Xcode管理和编译项目
3.1首先创建一个Mac OS下的Bundle工程
3.2在Build Settings-Search Paths中添加NaCl库
3.3添加MakeFile文件到项目中(可以使用SDK-Demo中的MakeFile,然后做适当修改)
TARGET是生成插件的名称,SOURCES用下面这种方式可以方便增删文件。其他应该不需要修改了
3.4添加一个External Build System的Target,用来编译NaCl代码(在需要编译程序的时候,需要选中这个Target来编译)。然后在Info中,添加编译参数和MakeFile的相对路径。
编译参数如果为空,默认是编译pnacl,newlib,glibc三种Release的程序。你可以指定TOOLCHAING=pnacl/newlib/glibc和VERSION=Release/Debug。windows下使用VS2010或以上版本,可以断点调试程序,但是Xcode还不支持。
如果你在编译代码的过程中,未使用的变量和普通警告都以错误形式出现,那需要修改SDK的tools目录中的common.mk文件:将NACL_CFLAGS和NACL_CXXFLAGS中的-Werror去掉,并加上-Wno-unused。
开发代码
这一部分没有什么可以讲啦,只要把Demo中的代码看一遍,就基本上可以开发了。官方网站也有很详细的API介绍:这里
这里要提一下,NaCl的SDK在39版本新增了一个js端发送消息并等待返回结果的机制(postMessageAndAwaitResponse,同时需要修改插件中接收消息的代码。以前只有postMessage,发送不等待),适用于那种非耗时的操作。
具体可以参考sdk目录中的examples/api/messaging项目
遇到的坑
1.FileIO操作只能异步
Chrome应该是怕这种耗时操作会影响页面的响应,所以才必须要异步来执行吧。这个地方尝试了不少方法,都行不通。后来只能选择预加载的模式来操作文件数据。
2.FileSystem根据域名来划分
每个调用插件的域名网站,都有独立的文件系统,这样有利于提高安全性,但是带来的弊端就是:即使是同一个插件,也不能几个域名共享本地文件数据(除非使用iframe)
3.使用FileIO存储文件到用户本地,需要申请空间
申请空间有两种方:
一是在manifest.json文件中添加unlimitedStorage权限,这做法适用于Chrome Web Store Application,在用户安装插件程序的时候,会出现下面的小黄条来向用户请求确认。
二是在js中使用navigator.webkitPersistentStorage.queryUsageAndQuota和navigator.webkitPersistentStorage.requestQuota(具体用法可以google)方法,当页面执行requestQuota时,也会出现小黄条。
只要用户不点击确定,那你的插件中跟FileIO相关的操作都会失败。
NaCl的优点
1.通过消息机制实现插件与Chrome的数据通信,使得代码比NPAPI简单很多
2.跨平台,一份代码,多处使用。但是这就意味着NaCl的限制也是非常多的
总结
从NPAPI移植到NaCl的过程,还有一些其他的坑,没有在这里一一列举了。这是一个没走几步,就需要停下来填坑的过程。或许这代表着NaCl根本不适用于我们的插件吧~只是现在还没有找到更好的方案,只能硬着头皮上了。
NaCl这种Chrome独家的API,增加了开发Web插件的成本,导致需要IE内核,Web Kit内核,Chrome三套代码,不好维护。真是希望以后有一种通用的API将它们统一起来。