zoukankan      html  css  js  c++  java
  • Server-Sent Events(HTML5 服务器发送事件)

    Server-Sent Events简介

    Server-Sent Events(SSE)用于网页自动获取服务器上更新的数据,它是一个实时性的机制。

    实时性获取数据的解决方案

    对于某些需要实时更新的数据(例如Facebook/Twitter 更新、估价更新、新的博文、赛事结果等)来说,有这么几种解决方案:

    Polling(轮询)

    在客户端重复的向服务端发送新请求。如果服务器没有新的数据更动,关闭本次连接。然后客户端在稍等一段时间之后,再次发起新请求,一直重复这样的步骤。

    Long-polling(长轮询)

    在长轮询中,客户端发送一个请求到服务端。如果服务端没有新的数据更动,那么本次连接将会被保持,直到等待到更新后的数据,返回给客户端并关闭这个连接。

    Server-Sent Events

    SSE类似于长轮询的机制,但是它在每一次的连接中,不只等待一次数据的更动。客户端发送一个请求到服务端 ,服务端保持这个请求直到一个新的消息准备好,将消息返回至客户端,此时不关闭连接,仍然保持它,供其它消息使用。SSE的一大特色就是重复利用一个连接来处理每一个消息(又称event)。

    WebSocket

    WebSocket不同于以上的这些技术,因为它提供了一个真正意义上的双向连接。WebSocket是HTML5中非常强大的新特性,已经得到广泛应用。(这里暂时不进行展开)

    一个基本例子——动态更新时间(基于Servlet)

    我们希望在html页面中显示一个动态变化的时间,这里使用Server-Sent Events来实现,在后台获取时间,不断发送给前台。

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
        <script>
            function start() {
                var eventSource = new EventSource("HelloServlet");
                eventSource.onmessage = function(event) {
                    document.getElementById("foo").innerHTML = event.data;
                };
            }
        </script>
    </head>
    <body>
        Time: <span id="foo"></span>
        
        <br><br>
        <button onclick="start()">Start</button>
    
    </body>
    </html>

    这是一个很简单的HTML页面,结合JS代码,我们现在是希望改变<span id="foo"></span>标签中的值,这是最纯粹的目的。下面分析代码:

    1.new出一个EventSource对象,这个对象就是用来请求服务断的,它的构造方法中需要一个请求的URL,来请求哪一个Servlet/Action等。。。

    2.利用EventSource对象的onmessage函数,得到服务端传递的数据。

    再来分析后端代码:

    public class HelloServlet extends HttpServlet {
        @Override
        public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // ContentType 必须指定为 text/event-stream
            resp.setContentType("text/event-stream");
            // CharacterEncoding 必须指定为 UTF-8
            resp.setCharacterEncoding("UTF-8");
            PrintWriter pw = resp.getWriter();
            for(int i=0; i<10; i++) {
                // 每次发送的消息必须以
    
    结束
    pw.write("data: " + System.currentTimeMillis() + " "); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } pw.close(); } }

    这里可以观察到,后端代码其实就是一个普通的Servlet(Web.xml省略),重写了Get方法,利用response对象得到的PrintWriter来写消息,这是一个大致的思路。

    1.设置ContentType为text/event-stream

    2.设置CharacterEncoding为UTF-8

    3.得到PrintWriter对象,写数据,格式为:   data: xxxx      注意一定要有两个 作为结尾

    这样就告诉了客户端:我发送了event-stream格式且编码为UTF-8的数据,数据长这样:

    data: xxxx

    然后客户端的JS代码利用EventSource对象的onmessage函数,监听到了服务端的数据更动,解析内容xxxx,即event.data = xxxx;

  • 相关阅读:
    Python——协程
    Linux——raid介绍
    Linux——网关介绍
    Linux——inode节点介绍
    算法:排序加二分查找
    Mysql主从复制作用和工作原理详解
    Selenium中错误:selenium.common.exceptions.ElementClickInterceptedException: Message: element click inte
    redis.exceptions.DataError: Invalid input of type: 'dict'. Convert to a byte, string or number first
    Python之requests错误Expecting value: line 1 column 1 (char 0)
    简述cookies和session的区别
  • 原文地址:https://www.cnblogs.com/shiyu404/p/6052816.html
Copyright © 2011-2022 走看看