DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> Web跨浏覽器進程通信(Web跨域)
Web跨浏覽器進程通信(Web跨域)
編輯:關於JavaScript     

  在之前一篇文章裡嘗試了跨浏覽器的數據共享,最後提到使用LocalConnection還可以實現跨浏覽器消息交互的可行性。

  花了兩個晚上簡略的研究了下,LocalConnection的單向通信非常的簡單,不過要實現多個終端交互,必須自己實現一套消息機制,見智見仁了。

  為了簡單演示,本例使用了基於廣播的觀察者模式:每個終端可以訂閱自己感興趣的主題,也可以向廣播發送消息,通知其他感興趣的終端。

  Demo: http://www.etherdream.com/FunnyScript/WebIPC/ (多開幾個浏覽器頁面小窗口,即可測試)

  比較遺憾的是最新版的Chrome浏覽器仍然無法和其他浏覽器進程交互:(

  如果沒有錯誤發生,應該就是如下的效果:

  在任何一個頁面上的操作,都會立即同步到其他頁面裡,只要Observe了感興趣的主題。

  為什麼要使用觀察者模式呢?因為跨進程的通信是比較耗資源的,所以不感興趣的消息可以直接不訂閱,而不是收到再放棄。

  LocalConnection是為單一的通信設計的,雖然使用很簡單,但可用的接口少之又少。想直接用它來廣播事件,或者消息路由,門都沒有。

  因此底層的消息發送上沒有太多可選余地,只能簡單的點對點發送。我們必須創建多個LocalConnection,來實現消息的匯聚和分發。

  LocalConnection真正能用的只有兩個方法:

    connect(name) —— 創建管道(每個LocalConnection只能創建一個管道,每個管道名只能有一個)

    send(name, ...) —— 向管道發送數據

  如果只有兩個終端通信,那麼一切都是那麼簡單。。。

  

  只需簡單的將消息發送給對方即可。

  不過有多個終端情況就大不相同了。由於我們是本地進程間通信,並沒有第三方服務器主持,加上LocalConnection只能點對點的發送消息。意味著每次廣播都要給其他所有的終端都發送一次,這樣復雜度就大大增加了。

  為了簡化結構,我們模擬一個LocalConnection作為Host,在第一次啟動時運行。其余的作為Client,每次廣播消息都提交給Host,由它來調度。

  

  Host維護著一個回調列表。當Client對某個主題(subject)感興趣時,可以發送<主題ID,自己的管道名>給Host來訂閱。於是Host就把此Client的管道名添加到該主題的回調列表裡。以後若有該主題的消息,即可根據回調列表通知訂閱的Client。

  為了能讓Host和Client通信更簡單,這裡使用channel+ID的命名規則,來創建管道名。

  Host的ID為空,於是Client發送數據只需send(channel)即可;

  Client的ID從1~100,選一個沒用被占用的作為管道名。Host回調時只需send(channel+id)就能通知對應的Client。

  然而,這個Host服務僅僅是假象的。我們根本沒法在頁面之外運行一個第三方服務,一切只能在頁面中實現!於是我們把第一次啟動的頁面作為Host。當這個頁面關閉時,我們再通知第二個頁面創建Host,以此類推。。。

  

  由於沒有第三方服務器,每個Client都可以兼職做Host。到這裡,你是不是想到了局域網游戲?由於沒有服務器,第一個創建的玩家便是主機。當他退出時,主機就交給了第二個玩家。如果他沒按正常步驟,強制退出了游戲,那就很有可以造成主機丟失,數據沒來得及轉移給下個玩家,導致游戲斷線結束。

  同樣,當我們Host所在頁面關閉時,會向所有Client發送一條退出消息。至於誰繼承王位,不用關心,誰先得知誰做~~ 唯一值得注意的就是:很多浏覽器不能正常觸發window.unload事件,這意外著Host可能還沒來得把回調列表移交給他的繼承者就已匆匆離去,於是後人就無法接管了。為了不讓這種情況出現,每當新的Host上任,就向所有的Client發送一個請求,讓大家把各自關注的主題重新發送一遍(之前關注的都保存著,就為了這個時候用)。因此,即使新上任的Host一無所有,大家也會把現狀告訴他,可立即投入工作中。

  若是強制關閉了Host所在的頁面進程,那麼主機丟失後一切都將會掛起。這時所有Client發送的數據都將有去無回,只有等到之後出現數據發送失敗,才得知Host已經掛了。這時誰先發現這個錯誤,誰就接管Host工作吧。

  當然,還可以考慮加上心跳機制,即使Host沒有掛掉,但其所在進程長時間占用CPU,導致LocalConnection無法響應消息事件,也可以考慮轉移Host了。

  由於時間限制,本例還有不少BUG,以後再慢慢完善。

  想看代碼可以浏覽:http://code.google.com/p/webipc/source/browse/

  事實上純粹的本地通信意義並不大,只有配合遠程服務進行消息的交互,才更有意義。例如用戶開了多個微博頁面,傳統的模型必須為每個頁面發起一個長連接,來保持實時的數據接收。如果使用跨浏覽器通信,那麼只需讓Host發起一個連接即可,其余的Client訂閱自己想要的主題,最終只需一個連接就可以。

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved