• 深入浅出ghostbuster剖析NodeJS与PhantomJS的通讯机制


    深入浅出ghostbuster剖析NodeJSPhantomJS的通讯机制

    蔡建良 2013-11-14

    . 让我们开始吧

    通过命令行来执行

    1) 进行命令窗口: cmd

    2) 进入resources-requested.js 所在目录:

    cd 你的目录ghostbusterghostbuster-master ests

    3) 执行nodejs代码: node resources-requested.js

    执行成功后,会在tests目录下会生成一个google.png图片。

    resources-requested.js

    这是一个nodejs的主文件,调用ghostbuster.js模块,用于对网页进行操作,代码如下:

    clip_image002

    ghostbuster.js

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

    clip_image004

    bridge.js

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

    clip_image006

    代码下载: http://download.csdn.net/detail/janehlp/6552571

    . 代码解析

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

    clip_image008

    谁来触发socket连接事件,这个当然是socket客户端。这是通讯最核心的地方。如果连接事件无法被触发,那回调函数就不会被执行。nodejs与phantomjs也无法进行通讯。

    . 触发socket连接事件的真相

    1) ghostbuster.spawn方法通过child_process模块的spawn方法调用phantomjs命令来执行bridge.js代码。phantomjs命令是一个c++写的exe文件,该文件目录必须在环境变量PATH中。

    clip_image010

    2) spawn(“phantomjs”,[bridge,port]执行全过程

    这里的port是传入bridge.js中的参数。

    clip_image012

    注意: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服务来响应,响应代码如下图:

    clip_image014

    ghostbuster.js中的http服务响应http://127.0.0.1:8089请求,并返回一个text/html格式的网页内容。网页内容来自conrolPage变量,该变量由getControlPage()方法赋值。

    getControlPage()方法返回什么呢?

    nodejs与phantomjs通过websocket来进行通讯。它们之间沟通的桥梁客户端页面,客户端页面相当于一个client.html文件。这个文件的内容如下:

    clip_image016

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

    clip_image018

    还是回到bridge.js代码中来,当phantomjs执行bridge.js,会生成一个类似client.html的页面。

    而这个页面中采用了socket.io来与服务端建立websocket连接,从而实现了与nodejs的通讯。

    clip_image020

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

    clip_image022

    注意:ghostbuster.js就是所谓的服务端。

    我们再来看看ghostbuster.js中连接事件被触发后回调函数的样子。

    clip_image024

    . 页面创建完整过程

    callback(p)执行的是resources-requested.js中的回调方法function(phantom){…}。

    function(phantom){…}方法使用ghostbuster中p对象的createWebPage来创建页面。

    操作网页之前必须先创建一个空白页面,然后再打开网址并进行其它操作。

    clip_image026

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

    clip_image028

    对象p封装了3个属性和5个方法。其中createWebPage是用于创建页面。

    让我们更深入了解一下创建页面的完整过程:

    1) resources-requested.js执行p对象中的createWebPage方法。

    clip_image030

    2) ghostbusert.js执行p. createWebPage方法,并调用了request方法。

    参数说明: properties为{settings:{loadImages:true}},callback为function(page){…}。

    clip_image032

    3) ghostbusert.js执行request方法,调用socket发出cmd命令。

    参数说明:args为[“createWebPage”,properties],callback为function(page){…},cbId为空。

    args.splice(0,0,cbId); 是指从第0个位置开始插入 cbId,即回调函数的索引。

    将回调函数缓存到requests数组,后面responseHandler方法还需要用到。

    clip_image034

    4) client.html页面接收到cmd命令,并执行alert(msg)方法。

    参数说明: msg为[cbId,“createWebPage”,properties]

    clip_image036

    5) bridge.js监听controlpage页面的alert事件,并执行createWebPage(msg)方法。

    参数说明: message为[cbId,“createWebPage”,properties]

    clip_image038

    6) bridge.js执行createWebPage(msg)方法创建页面对象,并调用respond方法返回信息。

    参数说明: req为[cbId,“createWebPage”,properties]数组对象。

    req[0]为cbId。index为页面索引。

    clip_image040

    7) bridge.js执行respond(args)方法通过页面的evaluate方法发送socket命令向nodejs服务端发送响应信息。

    参数说明: args为[cbId,“createWebPage”,index]

    clip_image042

    8) ghostbuster.js通过socket.on(“res”,responseHandler)对res命令设置监听处理responseHandler。

    参数说明:response为字符串,值为[cbId,“createWebPage”,index]。

    cb为resources-requested.js中的回调函数function(page) {…}。res为页面索引index。

    clip_image044

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

    clip_image046

    9) resources-requested.js的回调函数function(page) {…}。

    终于又回到主程序来了,这时我们可以通过WebPage对象来对页面做具体的业务功能,如打开一个页面进行截屏等操作。

    clip_image048

    . 页面创建流程图

    clip_image050

  • 相关阅读:
    jtopo
    转载model2
    转载model
    Vue -- 后台系统布局导航栏
    Vue -- iview表格 axiso调用接口数据
    Vue -- 视频&&下载 组件
    Vue -- echarts 折线图demo
    Vue -- axios封装
    Vue -- 验证码
    01 & 02 & 03笔记
  • 原文地址:https://www.cnblogs.com/janehlp/p/3423807.html
Copyright © 2020-2023  润新知