Chrome源碼剖析 【五】

來源:互聯網
上載者:User

【五】 Chrome的外掛程式模型1. NPAPI為了緊密的與各個開源瀏覽器團結起來,共同抗擊IE的壟斷,Chrome的外掛程式,也遵循了 NPAPI(Netscape Plugin Application Programming Interface)標準,支援這個標準的瀏覽器需要實現一組規定的API供外掛程式調用,這組API形如 NPN_XXX,比如NPN_GetURL,外掛程式可以利用這些API進行二次開發。而NPAPI外掛程式以一個Dll之類的作為物理載體(windows下dll,linux下是so...)進行提供,裡面同樣也實現了一組規定的API。形式包括 NP_XXXNPP_XXX,NP_XXX是系統需要預設調用的方法,用於認知這個外掛程式,比如NP_Initialize, 而NPP_XXX是用於外掛程式完成一些實際功能,比如NPP_New。。。所有的外掛程式dll都需要放置在指定目錄下(根據作業系統的不同而不同...),每個外掛程式可以處理一種或多種MIME格式的資料,比如application/pdf,說明該外掛程式可以處理pdf相關的文檔。在Chrome中鍵入about:plugins,可以查看當前Chrome中具有的外掛程式資訊。。。NPAPI是一個很經典的外掛程式方案, 用dll進行注入,用協定的API進行通訊,用字串描述外掛程式能力。外掛程式宿主(在這裡就是瀏覽器...),會根據能力描述,動態載入外掛程式,並負責外掛程式調用的流程和生命週期管理。而外掛程式中,負責真實邏輯的處理,並可以構造UI與使用者交流。以此類方式實現的外掛程式系統,往往是處理的邏輯比較固定適用範圍一般(用API寫死了邏輯...),但可擴充性不錯(用字串描述能力,可無限擴充...)。。。在Chrome中nphostapi.h中,定義了所有NPAPI相關的函數指標和結構,這個檔案放置在glue目錄下,如果看過前面碰過的文章就知道,在WebKit內肯定也有一套相同的東西;在npapi.h/.cc中,提供了Chrome瀏覽器端的NPN_XXX系列函數的實現;每一個外掛程式物理執行個體,用PluginLib類來表示,而每一個外掛程式的邏輯執行個體,用PluginInstance類來表示。這個概念牽強附會的可以用windows中的控制代碼來類比,當你想操作一個核心對象,你需要獲得一個核心對象的控制代碼,每個進程中的控制代碼肯定不相同,但後面的核心對象卻是同一個,核心對象的生命週期通過控制代碼的計數來控制,有人用則或,無人用則死(當然這個類比相當的牽強,主要是想說明引用計數和邏輯與物理的關係,但一個關鍵性的區別在於,PluginLib與PluginInstance都是在一個進程內的,不能跨越進程邊界...)。在Chrome中,PluginLib負責載入和銷毀一個dll,拿到所有匯出函數的函數指標,PluginInstance對這些東西進行了封裝,可以更好的來調用。。。關於NPAPI的更多細節,Chrome並沒有提供任何文檔,但是,各個先驅的瀏覽器們都提供了大量豐富的文檔。比如,你可以到這裡,查看firefox中的NPAPI文檔,基本通用。。。2. Chrome的多進程外掛程式模型Chrome的外掛程式模型,與早先的瀏覽器的最大不同,是它採用了多進程的方式,每一個外掛程式,都有一個單獨的進程來承載(Shift + Esc開啟Chrome進程管理器,可以看到現在已經載入的外掛程式進程...)。當WebKit進行頁面渲染的時候,發現了未知的MIME類型資料,它會告知給Browser進程,召喚它提供一個外掛程式來解析。如果該外掛程式還未載入,Browser會在指定目錄中搜尋出具有此實力的外掛程式(如果沒有此類人才只能作罷...),並為它建立一個進程,讓它負責所有的該外掛程式相關的任務,然後建立起一個IPC通路,與它“保留”。這套流程一定不會太陌生,因為它與Render進程的建立大同小異換湯不換藥。。。Plugin進程與Render進程最大的區別在於,Render需要與Browser進程大量通訊,因為它的HWND歸Browser老大掌管著,相關所有內容都需要通訊完成。但Plugin不需要與Browser頻繁聯絡,它大部分的通訊都是與Render進程發生的。如果Plugin與Render之間的通訊,還需要走Browser中轉一下,這就顯得有些脫褲子放屁了,雖然Browser是大頭,但不是冤大頭,它不會幹這種吃力不討好的事情。他只是做了一回Render與Plugin間的媒婆而已。當Plugin與Browser建立好了IPC通路後,它會讓Render建立一個新IPC通路,用以與Plugin通訊,IPC的有名管道名,經由Browser通知給Plugin。完成名字協商後,Render與Plugin的通訊關係就建立好了,它們之間就可以直接進行通訊了。。。整個通訊模式,可以看這裡。這是一個很標準的代理模式的應用,稍有瞭解的都可以跳過我後面會做的一段羅嗦的描述,一看官方文檔中的圖便能知曉。在Render進程端,WebPluginImpl是WebPlugin的一個子類,WebPlugin是供Webkit進行調用的一個介面,利用依賴倒置,實現了擴充。在Plugin進程端,實現了一個WebPluginDelegateImpl類,該類會調用PluginInstance的相關介面實現真實的外掛程式功能。這樣的話,只需要WebPluginImpl調用WebPluginDelegateImpl中的相應方法,就可以實現功能。但問題是WebPluginImpl與WebPluginDelegateImpl天各一方各處於一個進程,很顯然,這裡需要一個代理模式。這裡沿用了COM的架構,Delegate + Stub + Proxy。WebPluginImpl調用代理WebPluginDelegateProxy,該代理會將調用轉換成訊息,通過IPC發送給Plugin進程,在Plugin端,通過WebPluginDelegateStub監聽訊息,並轉換成對真實WebPluginDelegateImpl的調用,從而完成了跨進程的一個調用,反之亦然。。。3. Chrome的可擴充性總所周知,firefox通過三種方式進行自訂,外掛程式、擴充和皮膚。其中,外掛程式是使得瀏覽器能用,不會出現一大塊一大塊的無法顯示的地區;擴充是使得瀏覽器好用,可以簡單方便的進行功能的定製和個人化配置;皮膚是協助瀏覽器變得好看,畢竟羅蔔白菜,給有所愛。。。與之對比,來看Chrome。Chrome有了外掛程式,有了皮膚,但是沒有擴充。這就意味著,你很難為Chrome定製一些特色的功能。目前,所有對Chrome的功能擴充,都是通過書籤抑或是修改核心來實現的。前者能力太弱,後者開發起來太麻煩,容易出錯不提,還必須要與時俱進,跟上版本的變化,並且還不能自由的選擇或關閉。因此,這都不是長遠之計,Chrome提供一套類似於firefox的擴充機制,也許才是正道。據傳說,Chrome團隊正在琢磨這件事,不知道最終會出來個怎麼樣的結果,是儘力接近firefox降低移植成本,還是另立門戶特立獨行,我想可以拭目以待一把。。。在多進程模式下,Chrome的外掛程式還有一個問題,前面提到過,就是關於UI控制項的。由於NPAPI的標準,是允許外掛程式建立HWND視窗的,這就使得當Plugin繁忙,且Browser進程發起HWND的同步的時候,主進程被掛起,這個瀏覽器停滯。在Render進程中,解決這個問題的思路是控制許可權,不然Render建立HWND,到了Plugin中,這招不能使用,只能夠使用另一招,就是監管。不停的檢查Plugin是否太繁忙,無法響應,一旦發現,立即殺死該Plugin及其所處的頁面。這就好比你想解決奶中有三氯氰胺的問題,要麼控制奶源,不從奶站購買全部用自家的,要麼加強監管,提高檢查力度防止隱患。兩種策略的優缺點一眼便知,依照不同環境採取不同策略即可。。。總體說來,Chrome的可擴充性著實一般,不過Chrome還處於Beta中,我們可以繼續期待。。。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.