• html5之服务器推送事件


    用于服务器实时向客户端推送消息,这个是单向推送server to client

    服务器端

      header头

      要想服务器端推送:在服务器端的报头要定义:
      header('Content-Type:text/event-stream'),服务器发送的响应内容应该使用这种`text/event-stream`的MIME;这样客户端才能理解你这是发送的不是普通的数据,   eventsource对象才能识别

      事件流

     服务器端发送事件流(内容);
     每执行一次php文件就产生一个事件流;
     事件流是由多个消息组成;
     消息是一个后面都有一个空行作为分隔符
     一个消息就是一个事件
     一个消息可以由一个或者多个字段组成
     字段是由字段名,冒号,字段值(数据),`字段名:值`;
     产生一个空行(即两个换行符)代表一个事件(消息)的结束
     在一个文件中定义多个未命名事件,后面的会覆盖前面的,
     消息中的多个字段用一个` `(换行符)分隔
     一个消息的结束用` `(产生一个空行);
     一个字段的开始必须是以`data:`开头,例如`data:hello world! `,客户端会接受到`hello world!`,
     编码形式只能是使用utf-8,不能自己指定
     说的也是云里雾里,其实你只要知道我要用这种特定的格式来发送数据就行,直接下面的代码解释

    服务器代码

    我就解说下面三个消息,解释完了也就明白了,
    1. 开始:报头,这个是必须的,就是要告诉客户端,你要把我的数据放在eventSource对象中;
    2. 第一个消息:第一个字段是打印一个时间,第二个字段打印一个‘nihao’,第三个字段打印‘hehe’,第四个字段打印‘nihaoo’,第五个字段打印‘bbbb’;最后两个 代表消息的结束
    注意:每个字段后面是有一个 ,来告诉浏览器我这是一个字段,而两个 ,是告诉浏览器我这个消息结束了。每个字段的开头必须是:data:,这个一个没有事件名的消息
    3. 第二个事件是有事件名,有名字的事件是使用event:开头,值是事件名,这第二个消息就是定义了一个名字为hello的事件。
    4. 第三个消息:差别就是这次发送的是一个json

     //服务器代码
        <?php 
        header('Content-Type:text/event-stream');
        // header("Cache-Control:no-cache");//有的浏览器会缓存,如果默认是缓存的话就加上这句
        date_default_timezone_set('Asia/Shanghai');
        //第一个消息
        while(1) {
            echo 'data:'.date('Y-m-d H:i:s')."
    ";
            echo "data: nihao
    data: hehe
    ";
            echo "data: nihaoo
    ";
            echo 'data: bbbb';
            echo "
    
    ";
            //第二个消息
            echo "event: hello
    ";
            echo "data: world
    
    ";
            //第三个消息
            echo "event:hh
    ";
            echo 'data: {"time":"aaaa"}'."
    ";
            echo "
    
    ";
            flush();
            sleep(1);
        }
        ?>
    服务器代码

    客户端
    EventSource
    这个API,要使用它,必须先实例化,并且必须给他传递一个参数,这个参数就是请求服务器的地址
    `var ES = new EventSource('服务器地址')`;
    监听
    EventSource对象属性和方法
    属性 
     error
     message
     open
     readyState
     url

    方法
    close()

    - 当连接发生错误的时候触发error事件
    - 当成功连接时触发open事件
    - 当接收到没有命名的事件时触发message事件
    - readyState返回当前状态
    - 0 =>正在建立连接
    - 1 =>连接处于打开状态,正在调度事件
    - 2 =>没有建立连接
    - url返回页面地址
    - close(),关闭连接
    当成功连接后它会一直处于监听状态,监听服务器发送来的信息,如果断开了连接,客户端会自动重新进行连接,除非你用close关闭。

    命名事件
    命名事件的接收要用addEventListener来监听,用法就像我下面代码写的
    未命名事件
    用DOM0级的方法或者是DOM2级的方法都行
    `ES.onmessage = function(e){}`
    `ES.addEventListener('message',function(e){});`
    解析
    JSON
    如果接收的是json,则要先解析`JSON.parse(e.data)`;
    多字段
    对于多个字段的,如果向要解析出来每个字段来,就要使用正则表达式,由于浏览器会把整个消息变成一个字符串,并在每个字段后面添加一个换行符,而String类型有一个split方法,只需要用换行符作分隔,所以只需要`e.data.split(/s/)`,这就返回一个数组,数组的每一项就是一个字读的值

     //客户端代码
        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>服务器推送</title>
        </head>
        <body>
        <div id="box"></div>
        <div id="box2"></div>
        <div id="box3"></div>
        <script>
            var evtSource = new EventSource('server.php');
            var box = document.getElementById("box");
            var box2 = document.getElementById('box2');
            var box3 = document.getElementById('box3');
            //
            evtSource.onerror = function(e) {
            console.log('error');
            }
            evtSource.onopen = function(e) {
                console.log("open");
            }
            evtSource.onmessage = function (e) {
                //2015-06-12 22:09:04 nihao hehe nihaoo bbbb
                box.innerHTML = e.data;
                //["2015-06-12", "22:08:55", "nihao", "hehe", "nihaoo", "bbbb"]
                console.log(e.data.split(/s/));
                //http://127.0.0.1/server.php
                console.log(evtSource.url)
            }
            evtSource.addEventListener('hello',function(e) {
                //world
                box2.innerHTML = e.data;
            });
            evtSource.addEventListener('hh',function(evt) {
                //aaaa
                box3.innerHTML = JSON.parse(evt.data).time;
            });
        </script>
        </body>
        </html>

    问题
    在使用的过程中可能会遇到php进行了缓存,这样的会导致,客户端数据不能及时的更新,你需要在php.ini中禁止掉缓存 `output_buffering = On`这项你禁止掉,并且在php文件中`flush()`;

    很久没有在博客园写文章了,总是感觉要写出有点质量的文章才能拿出来,至少是自己认为的,但是写有点质量的文章,总是感觉自己水平不行。有时想记录学习笔记,于是我就在github上弄了一个静态网站,这里我会记录我的学习和复习过程,一些小的东西我也会记录的。地址:www.evil007.com。名字很吓人,就是为了霸气了。嘿嘿。 

    参考:

    w3c:eventsource:http://www.w3.org/TR/eventsource/
    MDN:https://developer.mozilla.org/zh-CN/docs/Server-sent_events/EventSource

  • 相关阅读:
    《ASP.NET1200例》实现投票的用户控件
    《转》这些年这些感悟
    《转》不要过打折的生活,当你发现这些你有了,说明你开始成熟了
    HTML控件ID和NAME属性及在CS页面获得.ASPX页面中HTML控件的值
    逻辑回归(1)
    MySQL笔记5-----索引(覆盖索引等)
    MySQL笔记4------面试问题
    MySQL-----笔记3:存储引擎
    Python可视化数据------seaborn
    树(2)-----leetcode(层、深度、节点)
  • 原文地址:https://www.cnblogs.com/todayhappy/p/4591904.html
Copyright © 2020-2023  润新知