深刻淺出ghostbuster剖析NodeJS與PhantomJS的通信機制

深刻淺出ghostbuster剖析NodeJSPhantomJS的通信機制html

蔡建良 2013-11-14node

 

. 讓咱們開始吧c++

經過命令行來執行web

1) 進行命令窗口: cmd數組

2) 進入resources-requested.js 所在目錄:瀏覽器

cd 你的目錄\ghostbuster\ghostbuster-master\tests緩存

3) 執行nodejs代碼: node resources-requested.jswebsocket

執行成功後,會在tests目錄下會生成一個google.png圖片。socket

 

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

相關文章
相關標籤/搜索