本篇將講述HTML5的服務器發送事件(server-sent event)html
Server-Sent 事件是單向消息傳遞,指的是網頁自動獲取來自服務器的更新。web
之前的作法是網頁不斷的詢問(向服務器發送請求)是否有可用的更新。經過服務器反饋以後,得到更新。ajax
咱們使用上篇HTML5簡單入門系列(四)web worker的技術簡單實現一下該輪訓方案,主動向服務器詢問是否有更新。後端
因爲web worker不能訪問document等對象,是不能和jQuery連用的,這裏咱們實現一個簡單的js原生ajax來實現向服務器發送請求。瀏覽器
一、新建一個WebForm頁面,做爲ajax請求的後端,代碼很簡單,只是返回當前時間便可,以下服務器
1 protected void Page_Load(object sender, EventArgs e) 2 { 3 try 4 { 5 Response.Write("data:" + DateTime.Now); 6 Response.Flush(); 7 } 8 catch(Exception ee) 9 { 10 } 11 }
ps:這裏我將webform的前臺頁面內容清空了,不然會同時返回頁面內容。多線程
二、按照web worker的使用方法,咱們新建外部js和主線程html頁面(和上篇示例中基本一致),代碼以下:ide
webworker2.jspost
onmessage = function (event) { ajaxFunction("WebForm2.aspx"); } function ajaxFunction(url) { var xmlHttp; var resText; try { // Firefox, Opera 8.0+, Safari xmlHttp = new XMLHttpRequest(); // 實例化對象 } catch (e) { // Internet Explorer try { xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { alert("您的瀏覽器不支持AJAX!"); return false; } } } xmlHttp.onreadystatechange = function () { if (xmlHttp.readyState == 4 && xmlHttp.status == 200) { postMessage(xmlHttp.responseText); } } xmlHttp.open("GET", url, true); xmlHttp.send(null); }
當web worker接收到主線程啓動的消息後,向webform發起請求。在XMLHTTPRequest的readystatechange事件中,服務器成功(200)返回後則postMessage回主線程更新頁面。ui
webworker2.html
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> </head> <body> web worker實時時間:<div id="workerTime"></div> <br /> 主線程獲取當前時間:<div id="curTime"></div> <button onclick="mainthread()">主線程獲取時間</button> <script> var interval; if (typeof Worker != undefined) { var worker = new Worker("webworker2.js"); worker.onmessage = function (event) { document.getElementById("workerTime").textContent = event.data; } interval = setInterval('worker.postMessage()', 1000); } function mainthread() { document.getElementById("curTime").textContent = new Date(); } function stop() { clearInterval(interval); worker.terminate(); } setTimeout(stop, 60000);//60秒以後清理interval </script> </body> </html>
這裏輪訓時間,就是interval = setInterval('worker.postMessage()', 1000); 根據須要適當調整。
這是以前經常使用的輪訓服務方案,並且咱們接住web worker實現了多線程輪訓。
再看看HTML5提供給咱們的方案。
一、新建一個webform頁面,用來充當服務器的數據更新。代碼以下:
protected void Page_Load(object sender, EventArgs e) { try { Response.ContentType = "text/event-stream"; Response.CacheControl = "no-cache"; Response.Write("data:" + DateTime.Now); Response.Flush(); } catch(Exception ee) { } }
注意:這裏webform的前臺內容依然存在,而上邊輪訓服務中我將其清空了。
二、新建一個html頁面,咱們在該頁面上實現主動數據更新。
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> </head> <body> <div id="result"></div> <script> if (typeof EventSource != undefined) { var source = new EventSource("WebForm1.aspx"); source.onmessage = function (event) { document.getElementById("result").innerHTML += event.type + ":" + event.data + "<br />"; } source.onerror = function (event) { document.getElementById("result").innerHTML += event.type + "<br />"; } } else { document.getElementById("result").innerHTML = "no support EventSource"; } </script> </body> </html>
在上面的例子中,咱們使用 onmessage 事件來獲取消息,onerror獲取錯誤消息。不過還能夠使用其餘事件:
事件 | 描述 |
---|---|
onopen | 當通往服務器的鏈接被打開 |
onmessage | 當接收到消息 |
onerror | 當錯誤發生 |
是否是簡潔多了?
另外須要說明的是,EventSource並非實時的獲取服務器更新。在Chrome瀏覽器中是每3秒更新一次,在Firefox瀏覽器中是每隔5秒更新一次
不過LZ有點不明白,爲何執行了onmessage以後仍是會執行onerror呢?並且error事件中也沒有太多相關信息可查看...麻煩知道的園友大牛指教!
好吧,也沒啥好說的,就這樣吧。