HTML5簡單入門系列(五)

前言

本篇將講述HTML5的服務器發送事件(server-sent event)html

Server-Sent 事件

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         }
View Code

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);
}
View Code

當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>
View Code

這裏輪訓時間,就是interval = setInterval('worker.postMessage()', 1000);  根據須要適當調整。

這是以前經常使用的輪訓服務方案,並且咱們接住web worker實現了多線程輪訓。

HTML5 EventSource

再看看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)
            {
            }
        }
View Code

注意:這裏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>
View Code

在上面的例子中,咱們使用 onmessage 事件來獲取消息,onerror獲取錯誤消息。不過還能夠使用其餘事件:

事件 描述
onopen 當通往服務器的鏈接被打開
onmessage 當接收到消息
onerror 當錯誤發生

是否是簡潔多了?

另外須要說明的是,EventSource並非實時的獲取服務器更新。在Chrome瀏覽器中是每3秒更新一次,在Firefox瀏覽器中是每隔5秒更新一次

  

不過LZ有點不明白,爲何執行了onmessage以後仍是會執行onerror呢?並且error事件中也沒有太多相關信息可查看...麻煩知道的園友大牛指教!

小結

好吧,也沒啥好說的,就這樣吧。

相關文章
相關標籤/搜索