深入浅出ghostbuster剖析NodeJS与PhantomJS的通讯机制
深入浅出ghostbuster剖析NodeJS与PhantomJS的通讯机制
蔡建良 2013-11-14
一. 让我们开始吧
通过命令行来执行
1) 进行命令窗口: cmd
2) 进入resources-requested.js 所在目录:
cd 你的目录\ghostbuster\ghostbuster-master\tests
3) 执行nodejs代码: node resources-requested.js
执行成功后,会在tests目录下会生成一个google.png图片。
resources-requested.js
这是一个nodejs的主文件,调用ghostbuster.js模块,用于对网页进行操作,代码如下:

ghostbuster.js
这是一个nodejs的文件,导出一个spawn方法。代码如下。

bridge.js
这是一个phantomjs的文件,代码如下。

代码下载: http://download.csdn.net/detail/janehlp/6552571
二. 代码解析
ghostbuster.spawn方法传入两个参数,一个是端口号8089,另一个是匿名的回调函数function(phantom){….},回调函数在ghostbuster.spawn方法内部被调用,调用时机是在socket连接监听事件被触发时发生。如下图所示:

谁来触发socket连接事件,这个当然是socket客户端。这是通讯最核心的地方。如果连接事件无法被触发,那回调函数就不会被执行。nodejs与phantomjs也无法进行通讯。
三. 触发socket连接事件的真相
1) ghostbuster.spawn方法通过child_process模块的spawn方法调用phantomjs命令来执行bridge.js代码。phantomjs命令是一个c++写的exe文件,该文件目录必须在环境变量PATH中。

2) spawn(“phantomjs”,[bridge,port]执行全过程
这里的port是传入bridge.js中的参数。

注意:bridge.js代码是由phantomjs解析执行,而ghostbuster.js是由nodejs解析执行,不要搞混了。两者的内置模块是不相同的,不能混合使用。
webpage、fs、system是phantomjs内置模块。
bridge.js代码首先先会创建一个页面变量controlpage,并打开http://127.0.0.1:8089网址。
这个就好像你用浏览器打开一个新的页面,并在地址栏中输入网址http://127.0.0.1:8089。
由于前面ghostbuster.js已创建了一个http服务,监听端口是8089。因此http://127.0.0.1:8089由ghostbuster.js中的http服务来响应,响应代码如下图:

ghostbuster.js中的http服务响应http://127.0.0.1:8089请求,并返回一个text/html格式的网页内容。网页内容来自conrolPage变量,该变量由getControlPage()方法赋值。
getControlPage()方法返回什么呢?
nodejs与phantomjs通过websocket来进行通讯。它们之间沟通的桥梁客户端页面,客户端页面相当于一个client.html文件。这个文件的内容如下:

getControlPage()方法就是返回上面这个client.html的内容,方法如下图所示:

还是回到bridge.js代码中来,当phantomjs执行bridge.js,会生成一个类似client.html的页面。
而这个页面中采用了socket.io来与服务端建立websocket连接,从而实现了与nodejs的通讯。

client.html执行如下脚本与node服务端连接,连接成功后会触发connection事件,回调函数也会被执行。

注意:ghostbuster.js就是所谓的服务端。
我们再来看看ghostbuster.js中连接事件被触发后回调函数的样子。

四. 页面创建完整过程
callback(p)执行的是resources-requested.js中的回调方法function(phantom){…}。
function(phantom){…}方法使用ghostbuster中p对象的createWebPage来创建页面。
操作网页之前必须先创建一个空白页面,然后再打开网址并进行其它操作。

function(phantom)这个方法中的参数phantom是ghostbuster.js中的变量p。p这个对象封装了phantomjs命令。让我们看看对象p封装了哪些方法。

对象p封装了3个属性和5个方法。其中createWebPage是用于创建页面。
让我们更深入了解一下创建页面的完整过程:
1) resources-requested.js执行p对象中的createWebPage方法。

2) ghostbusert.js执行p. createWebPage方法,并调用了request方法。
参数说明: properties为{settings:{loadImages:true}},callback为function(page){…}。

3) ghostbusert.js执行request方法,调用socket发出cmd命令。
参数说明:args为[“createWebPage”,properties],callback为function(page){…},cbId为空。
args.splice(0,0,cbId); 是指从第0个位置开始插入 cbId,即回调函数的索引。
将回调函数缓存到requests数组,后面responseHandler方法还需要用到。

4) client.html页面接收到cmd命令,并执行alert(msg)方法。
参数说明: msg为[cbId,“createWebPage”,properties]

5) bridge.js监听controlpage页面的alert事件,并执行createWebPage(msg)方法。
参数说明: message为[cbId,“createWebPage”,properties]

6) bridge.js执行createWebPage(msg)方法创建页面对象,并调用respond方法返回信息。
参数说明: req为[cbId,“createWebPage”,properties]数组对象。
req[0]为cbId。index为页面索引。

7) bridge.js执行respond(args)方法通过页面的evaluate方法发送socket命令向nodejs服务端发送响应信息。
参数说明: args为[cbId,“createWebPage”,index]

8) ghostbuster.js通过socket.on(“res”,responseHandler)对res命令设置监听处理responseHandler。
参数说明:response为字符串,值为[cbId,“createWebPage”,index]。
cb为resources-requested.js中的回调函数function(page) {…}。res为页面索引index。

WebPage方法在ghostbuster.js中定义如下:

9) resources-requested.js的回调函数function(page) {…}。
终于又回到主程序来了,这时我们可以通过WebPage对象来对页面做具体的业务功能,如打开一个页面进行截屏等操作。

五. 页面创建流程图

深入浅出ghostbuster剖析NodeJS与PhantomJS的通讯机制的更多相关文章
- v78.01 鸿蒙内核源码分析(消息映射篇) | 剖析LiteIpc(下)进程通讯机制 | 百篇博客分析OpenHarmony源码
百篇博客分析|本篇为:(消息映射篇) | 剖析LiteIpc(下)进程通讯机制 进程通讯相关篇为: v26.08 鸿蒙内核源码分析(自旋锁) | 当立贞节牌坊的好同志 v27.05 鸿蒙内核源码分析( ...
- 深入剖析C/C++函数的参数传递机制
2014-07-29 20:16 深入剖析C/C++函数的参数传递机制 C语言的函数入口参数,可以使用值传递和指针传递方式,C++又多了引用(reference)传递方式.引用传递方式在使用上类 ...
- 【工业串口和网络软件通讯平台(SuperIO)教程】八.SuperIO通讯机制与设备驱动对接的说明
SuperIO相关资料下载:http://pan.baidu.com/s/1pJ7lZWf 1.1 通讯机制说明 通讯的总体机制采用呼叫应答方式,就是上位机软件主动发送请求数据命令,下位机终端接 ...
- 【工业串口和网络软件通讯平台(SuperIO)教程】一.通讯机制
1.1 应用场景 通讯平台的交互对象包括两方面:第一.与硬件产品交互.第二.与软件产品交互.基本这两方面考虑,通讯平台一般会应用在两个场景: 1)通讯平台应用在PC机上 主要应用在自动站的工控机 ...
- <MFC_1>深入剖析MFC的WinMain和消息机制
一.开篇引论 熟悉Win32开发的朋友,应该非常了解它的基本组成和流程 1. WinMain:书写窗口类(WNDCLASS) -> 注册窗口类 -> 创建窗口 -> 显示窗口和更新窗 ...
- ActiveMQ之 TCP通讯机制
ActiveMQ支持多种通讯协议TCP/UDP等,我们选取最常用的TCP来分析ActiveMQ的通讯机制.首先我们来明确一个概念: 客户(Client):消息的生产者.消费者对ActiveMQ来说都 ...
- 一篇文章了解相见恨晚的 Android Binder 进程间通讯机制【转】
本文转载自:https://blog.csdn.net/freekiteyu/article/details/70082302 Android-Binder进程间通讯机制 概述 最近在学习Binder ...
- 深度剖析java中JDK动态代理机制
https://www.jb51.net/article/110342.htm 本篇文章主要介绍了深度剖析java中JDK动态代理机制 ,动态代理避免了开发人员编写各个繁锁的静态代理类,只需简单地指定 ...
- 面试题: nodejs 的事件轮询机制
setTimeout(function(){ console.log('setTimeout()执行了') },0) setImmediate(function(){ console.log('set ...
随机推荐
- AngularJS学习笔记2——AngularJS的初始化
本文主要介绍AngularJS的自动初始化以及在必要的适合如何手动初始化. Angular <script> Tag 下面通过一小段代码来介绍推荐的自动初始化过程: <!doctyp ...
- My SQL InnoDB 1217 - Cannot delete or update a parent row:aforeign key constraint fals
InnoDB 允许有外键 MyISAM 不允许有外键 InnoDB修改成MyISAM 证明有外键 一张表如果有其他表的外键关联的是它 它也不能是MyISAM 来自为知笔记(Wiz)
- TCP建立连接的三次握手过程
TCP是因特网中的传输层协议,使用三次握手协议建立连接,下面是TCP建立连接的全过程. 上图画出了TCP建立连接的过程.假定主机A运行的是TCP客户程序,B运行的是TCP服务器程序.最初两端的TCP进 ...
- Linux命令-cut
cut命令用于通过列来提取文本字符 格式:cut [参数] 文本 将/etc/paswd文件以:分割(-d:),获取第七列的内容(-f1) [root@localhost test]# cut -d: ...
- Android 实现Path2.0中绚丽的的旋转菜单
上图先: 那么下面开始吧~ 首先,将整个菜单动画分解开来. 1. 一级菜单按钮的旋转动画2个,十字和叉叉状态的转换. 2. 二级菜单按钮的平移动画2个,弹簧效果的in和out ...
- 高斯判别分析 Gaussian Discriminant Analysis
如果在我们的分类问题中,输入特征xx是连续型随机变量,高斯判别模型(Gaussian Discriminant Analysis,GDA)就可以派上用场了. 以二分类问题为例进行说明,模型建立如下: ...
- php抽象 与接口
抽象方法和抽象类 PHP5支持抽象类和抽象方法.抽象类不能直接被实例化,你必须先继承该抽象类,然后再实例化子类.抽象类中 至少要包含一个抽象方法.如果类方法被声明为抽象的,那么其中就不能包括具体的功能 ...
- git常见操作--忽略文件以及常用命令【转】
转自:http://www.cnblogs.com/elfsundae/archive/2011/07/17/2099698.html References: http://stackoverflow ...
- 【AStar】初赛第一场
1. All X1.1 基本思路k和c的范围都不大,因此可以考虑迭代找循环节,然后求余数,判定是否相等.这题还是挺简单的.1.2 代码 /* 5690 */ #include <iostream ...
- MongoDB 学习笔记(二) 高级查询
1.条件运算符 2.$all 匹配所有 3.$exists 判断字段是否存在 4.NUll 值处理 5.$mod 取模处理 6.$ne 不等于 7. $in 包含,与sql用法相同 8. $nin 不 ...