PHP中Push(推送)技術的研討 (轉載)

來源:互聯網
上載者:User
PHP中Push(推送)技術的探討 (轉載)

? ? ?(轉載:?http://vistaswx.com/blog/article/php-server-push)。

? ? ? 找了很多資料,這篇資料是感覺解釋的最清楚的。拷貝下來,以備後用。?

? ? ?隨著人們對Web即時應用需求的不斷上升,Server Push(推送)技術在聊天、訊息提醒尤其是社交網路等方面開始興起,成為即時應用的資料流核心。這篇日誌試圖探討的便是各種適合於PHP的Push的實現方式以及其優劣。

1. 什麼是Server Push

想象在聊天應用中,如果使用傳統的ajax來承擔訊息的傳入,那麼一般是通過每隔一定時間拉取一次資訊的方式實現,但是其實這種方式有大量查詢是浪費的。聊天等Web應用更需要伺服器在特定時間來主動告知前端有新的訊息(Push),而不是前端每時每刻問伺服器:“來訊息了嗎?”(Pull)。這也正是為什麼這個技術常被叫做反向ajax。

其他別名:Comet,反向Ajax

?

2. 如何?Push

其實所謂的推送技術也沒有多麼複雜,目前從大類上有3種,一種仍然建立在ajax基礎上,還有一種建立在架構基礎上,最後一種拋棄了傳統的HTTP協議,使用Flash或者HTML5的WebSockets技術。接下來將對這三種類別產生的不同的方式進行探討。

?

1) Ajax 長輪詢

Ajax長輪詢從本質上來說仍然是一種pull,但是即時性較高,無用請求減少很多,是一種不錯的Push實現方案。不過它只減少了網路上的無謂消耗。

核心:?用戶端發起一個ajax請求,服務端將請求擱置(pending)或者說掛起,直到到了逾時時間(timeout)或需要推送時返回;用戶端則等待ajax返回後處理資料,再發起下一個ajax請求。

優點:?相容性較高,實現簡單

缺點:?對於php這種語言來說,如果要做到即時,那麼服務端就要承受大得多的壓力,因為擱置到什麼時候往往是不確定的,這就要php指令碼每次擱置都進行一個while迴圈。
當然,如果伺服器重新整理每秒級,那尚可接受,只是即時性上退化了。

注意:?瀏覽器有串連數限制。我得出的結論是如果當前頁面上有一個ajax請求處於等待返回狀態,那麼其他ajax請求都會被擱置(Chrome, Firefox已測)。似乎跟頁面標記有關,一個規範的HTML可以同時有多個請求。如果頁面有一般ajax需求怎麼辦?解決方案是開個架構,架構中使在另一個網域名稱下進行Comet長輪詢,需要注意跨域問題。

PHP實現:?Jquery+php實現comet

相關:?Ajax跨域和js跨域解決方案

?

2) Frame 長串連

受到ajax啟發,出現了架構下的長串連。

核心:?Frame中發起一個普通請求,伺服器將其擱置;需要推送時輸出直接執行
指令碼,然後繼續保持串連。如果擔心逾時問題可以改成架構論詢。

優點:?與1一樣具有高相容特性

缺點:?最大的問題是如果架構在載入,那麼瀏覽器就好一直顯示“載入中”,這就弱爆了(解決方案參見文末的相關閱讀資源)。同樣伺服器也要能hold住大量迴圈……另外,是否有同域串連限制沒測試。

?

3) Flash/HTML5 WebSockets

用flash來發起WebSockets,秒殺前面一切問題。

優點:?標準化, RealTime, Push

缺點:?伺服器需要能應對WebSockets;還有如果既沒有Flash又不支援HTML5的怎麼辦?

PHP實現:?Start Using HTML5 WebSockets Today

?

6) 使用相容封裝層(socket.io)

以上每種方法都有優劣,那麼終極解決方案便是合在一起!能WebSockets時候就WebSockets,不支援HTML5特性就退化到Flash,沒有Flash則退化到Ajax長輪詢。這也是我的Rainbowfish所採用的方式。

優點:?高度封裝,編寫非常容易,幾乎不需要關心如何去實現的。即時,超低負載,高並發。

缺點:?其實算不上缺點,socket.io的伺服器端要求是node.js,而不是php。

個人看法:?如果你是外掛式主控件,能運行程式,那麼socket.io配合node.js是個非常高效的選擇。為什麼呢?因為它還可以避免php的服務端高負載。

Rainbowfish的訊息系統通過這種方式實現: 所有用戶端都通過socket.io掛在nodejs伺服器上(注意: 只是掛著,不需要任何迴圈,因為它是事件驅動的);需要推送訊息了,伺服器就與nodejs通訊(比如訪問某個地址來實現),告訴它推送什麼訊息到哪裡;nodejs收到推送訊號後,則通過socket.io即時傳輸資料給瀏覽器。這個其實也是一條單向的路,因為nodejs伺服器不具備與php通訊的能力,實際上也不需要,網頁上直接連php就可以了。

?

3. 結束語

事實上,第一個方法(Ajax Long Pull)是一個不錯的方法,只是如果使用php完成的話伺服器負載上有點大,但這其實是通病;而最後列舉的socket.io方案完全避免了這個問題,因為它屬於另一種架構,並且這種組合也可以配合幾乎所有的指令碼語言實現push。

對於即時性要求非常高的應用,或許使用php實現即時部分並不是一個好的選擇,將會面臨非常大的伺服器負載(可以通過編寫支援等待事件的擴充來解決這個問題);如果只是訊息提示等,則可以調整伺服器上重新整理的間隔降低到秒的層級,負載尚可接受。不過無論哪種用途,配合那些非阻塞語言或許才是最好的選擇。

?

4. 相關閱讀

How to implement COMET with PHP

Start Using HTML5 WebSockets Today

Comet(Wikipedia)

Ajax跨域和js跨域解決方案

Jquery+php實現comet

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.