• HTML5简单入门系列(五)


    前言

    本篇将讲述HTML5的服务器发送事件(server-sent event)

    Server-Sent 事件

    Server-Sent 事件是单向消息传递,指的是网页自动获取来自服务器的更新。

    以前的做法是网页不断的询问(向服务器发送请求)是否有可用的更新。通过服务器反馈之后,获得更新。

    轮训方案

    我们使用上篇HTML5简单入门系列(四)web worker的技术简单实现一下该轮训方案,主动向服务器询问是否有更新。

    由于web worker不能访问document等对象,是不能和jQuery连用的,这里我们实现一个简单的js原生ajax来实现向服务器发送请求。

    1、新建一个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的前台页面内容清空了,否则会同时返回页面内容。

    2、按照web worker的使用方法,我们新建外部js和主线程html页面(和上篇示例中基本一致),代码如下:

    webworker2.js

    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回主线程更新页面。

    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提供给我们的方案。

    1、新建一个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的前台内容依然存在,而上边轮训服务中我将其清空了。

    2、新建一个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事件中也没有太多相关信息可查看...麻烦知道的园友大牛指教!

    小结

    好吧,也没啥好说的,就这样吧。

  • 相关阅读:
    xgboost中XGBClassifier()参数详解
    xgboost使用经验总结
    特征选择之Chi卡方检验
    ldd 查看程序依赖库
    paddle——docker实践
    paddle实践
    java常用设计模式
    Java内存模型
    什么是线程?
    MySQL数据库提供了那些函数?
  • 原文地址:https://www.cnblogs.com/cotton/p/4384088.html
Copyright © 2020-2023  润新知