JavaScript表達行為,css表達外觀,注意HTML既表達結構(邏輯結構),又表達內容(數據本身)通常需要更新數據時,並不需要更新結構,正是這種不改變組織結構僅改變數據的訴求,推動了數據拉取和數據推送技術的產生。
SSE是一種允許服務器端向客戶端推送新數據(簡稱數據推送)的HTML5技術。數據推送有兩種替代方案:無更新方案和數據拉取方案。
無更新方案:
加載完畢HTML之後,得到一個HTML頁面,之後浏覽器會請求圖片、CSS文件和JavaScript文件等,他們都是浏覽器可以緩存的靜態文件。如果頁面使用後端語言,比如PHP、Ruby和Python等為用戶動態生成HTML的語言。
數據拉取方案:
浏覽器會基於一些用戶行為,或在一定時間之後,或基於某種別的觸發方案,向服務器端請求或全部更新數據,通過javascript或一個meta標簽能夠命令整個頁面重新加載。我們所熟悉的Ajax技術只被用於請求最新數據,當收到數據時,javascript函數會利用它來局部更新DOM。數據拉取的要義:僅拉取新數據,並且只更新頁面中受影響部分。
以上的都不是數據推送,數據推送不是靜態文件,也不涉及浏覽器為更新數據而發起請求,數據推送是由服務器選擇客戶端發送新數據。
當數據源有新數據時,服務器端能立刻發送給一個或多個客戶端,而不用等客戶端來請求,這些新數據可能是突發新聞、最新股票、上線朋友的聊天信息、新的天氣預報、策略游戲中的下一步等。
SSE適用於更新頻繁、低延遲並且數據都是從服務端到客戶端。它和WebSocket的區別:
1)便利,不需要添加任何新組件,用任何習慣的後端語言和框架就能繼續使用,不用為新建虛擬機弄一個新的IP或新的端口號而勞神。
2)服務器端的簡潔。因為SSE能在現有的HTTP/HTTPS協議上運作,所以它能夠直接運行於現有的代理服務器和認證技術。
WebSocket相較SSE最大的優勢在於它是雙向交流的,這意味著服務器發送數據就像從服務器接受數據一樣簡單,而SSE一般通過一個獨立的Ajax請求從客戶端向服務端傳送數據,因此相對於WebSocket使用Ajax會增加開銷。因此,如果需要以每秒一次或者更快的頻率向服務端傳輸數據,就應該用WebSocket,
具體代碼如下:
html
<!doctype html> <html> <head> <meta charset="UTF-8"> <title>basic SSE test</title> </head> <body> <pre id = "x">initializting...</pre> <!--之所以使用pre標簽而不是p或者div是為了確保數據能以它被接受時的格式呈現,而不會修改或格式化--> </body> <script> var es = new EventSource("basic_sse.php"); es.addEventListener("message",function(e){ //e.data document.getElementById("x").innerHTML += "\n"+e.data; },false);//使用false表示在冒泡階段處理事件,而不是捕獲階段。 </script> </html>
需要注意的是:使用服務器端數據之前最好做一下檢查,以防潛在的javascript注入攻擊。
php
<?php header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); $time = date('r'); echo "data: The server time is: {$time}\n\n"; flush(); ?>
“Content-Type: text/event-stream"是專門為SSE設計的MIME類型,
效果截圖
什麼時候數據推送是錯誤的選擇
首先考慮靜態的情況,不引入數據推送,每當用戶打開一個頁面,在浏覽器和服務器之間就會打開i一個套接字連接,服務器手機信息然後返回給用戶,可能很簡單,就像從磁盤上加載一個靜態的HTML文件或一張圖片一樣,也可能很復雜,就像要運行一段用以連接很多數據庫的後台語言。這裡的關鍵點就是,一旦返回了所需的信息,套接字就會關閉,每個HTTP請求都會打開一個這種生命周期相對較短的套接字連接,這些套接字是服務器上有限的資源,每當它們完成既定任務,就會被回收以循環再利用。
現在對比看一下數據推送。一個請求永遠不會完成,總是有很多信息要發送,所以套接字會一直保持打開狀態。顯然,因為它們是有限的資源,所以同一時刻的SSE連接數會有限制。
想象一種情況,你在為你最新的應用提供電話服務支持,有10個接線中心員工為1000個用戶提供服務,用戶遇到問題,其中一個接線員接線,然後掛線。新的客戶呼叫在排隊,知道其中一個接線員掛線,這是典型的網絡服��模式。
但是,現在有個客戶打過來說,我現在沒有問題,但是接下來幾個小時都會用到你們的產品,並且如果遇到問題,我希望你們立即回復。這個客戶將與接線員保持通話幾個小時,那麼呼叫中心的10%服務資源就被浪費。如果有10個這樣的客戶,那麼其他990個客戶就無法呼叫。這就是數據推送模式。
當然,這並不總是壞事,如果這個客戶一下午每隔幾秒鐘就有一個問題,這種情況保持電話通暢不但沒有浪費10%服務資源,反而會增加。因為每個問題都需要新打一個電話(就像數據拉取),接線員需要花額外的時間,驗證客戶身份,調出賬戶,降低服務效率。保持電話通常不僅使得客戶更滿意,也會提高呼叫中心的工作效率,這就是數據推送的最適合場景。
--------------------------------------分割線 --------------------------------------
HTML5 地理位置定位(HTML5 Geolocation)原理及應用 http://www.linuxidc.com/Linux/2012-07/65129.htm
HTML5移動開發即學即用(雙色) PDF+源碼 http://www.linuxidc.com/Linux/2013-09/90351.htm
HTML5入門學習筆記 http://www.linuxidc.com/Linux/2013-09/90089.htm
HTML5移動Web開發筆記 http://www.linuxidc.com/Linux/2013-09/90088.htm
HTML5 開發中的本地存儲的安全風險 http://www.linuxidc.com/Linux/2013-06/86486.htm
《HTML5與CSS3權威指南》及相配套源碼 http://www.linuxidc.com/Linux/2013-02/79950.htm
關於 HTML5 令人激動的 10 項預測 http://www.linuxidc.com/Linux/2013-02/79917.htm
HTML5與CSS3實戰指南 PDF http://www.linuxidc.com/Linux/2013-02/79910.htm
--------------------------------------分割線 --------------------------------------