您的位置:威尼斯城vnsc登入平台 > 网络信息 > Server-Sent Events(HTML5 服务器发送事件),server-

Server-Sent Events(HTML5 服务器发送事件),server-

2019-11-01 11:39

Server-Sent Events(HTML5 服务器发送事件),server-senthtml5

传统的WEB应用程序通信时的简单时序图:

Server-Sent Events简介

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

威尼斯城vnsc登入平台 1

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

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

现在Web App中,大都有Ajax,是这样子:

Polling(轮询)

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

威尼斯城vnsc登入平台 2

Long-polling(长轮询)

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

 

Server-Sent Events

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

HTML5有一个Server-Sent Events(SSE)功能,允许服务端推送数据到客户端。(通常叫数据推送)。基于数据推送是这样的,当数据源有新数据,它马上发送到客户端,不需要等待客户端请求。这些新数据可能是最新闻,最新股票行情,来自朋友的聊天信息,天气预报等。

WebSocket

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

 

威尼斯城vnsc登入平台 3

一个基本例子——动态更新时间(基于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: 

    <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++) {
            // 每次发送的消息必须以nn结束

            pw.write("data: " + System.currentTimeMillis() + "nn");
            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 nn      注意一定要有两个nn作为结尾

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

data: xxxx nn

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

 

http://www.bkjia.com/Javabc/1171750.htmlwww.bkjia.comtruehttp://www.bkjia.com/Javabc/1171750.htmlTechArticleServer-Sent Events(HTML5 服务器发送事件),server-senthtml5 Server-Sent Events简介 Server-Sent Events(SSE)用于网页自动获取服务器上更新的数据,它是一...

数据拉与推的功能是一样的,用户拿到新数据。但数据推送有一些优势。 你可能听说过Comet, Ajax推送, 反向Ajax, HTTP流,WebSockets与SSE是不同的技术。可能最大的优势是低延迟。SSE用于web应用程序刷新数据,不需要用户做任何动作。
你可能听说过HTML5的WebSockets,也能推送数据到客户端。WebSockets是实现服务端更加复杂的技术,但它是真的全双工socket, 服务端能推送数据到客户端,客户端也能推送数据回服务端。SSE工作于存在HTTP/HTTPS协议,支持代理服务器与认证技术。SSE是文本协议你能轻易的调试它。如果你需要发送大部二进制数据从服务端到客户端,WebSocket是更好的选择。关于SSE与WebSocket的区别,本文下面会讲到。

 

HTML5 服务器发送事件(server-sent event)允许网页获得来自服务器的更新
Server-Sent 事件 - 单向消息传递
Server-Sent 事件指的是网页自动获取来自服务器的更新。
以前也可能做到这一点,前提是网页不得不询问是否有可用的更新。通过服务器发送事件,更新能够自动到达。
例子:Facebook/Twitter 更新、估价更新、新的博文、赛事结果等。

浏览器支持(所有主流浏览器均支持服务器发送事件,除了 Internet Explorer。)

EventSource 推送(ajax普通轮询):

威尼斯城vnsc登入平台 4

处理过程:

客户端建立EventSource对象,对服务器通过http协议不断进行请求。服务器对客户端的响应数据格式有四部分构成,event,data,id,空格行。客户端接收到服务器端的响应数据之后,根据event事件值,找到EventSource对象对应的事件监听器。

 

接收 Server-Sent 事件通知
EventSource 对象用于接收服务器发送事件通知:

    //创建一个新的 EventSource 对象,规定发送更新的页面的 URL
    var source = new EventSource("../api/MyAPI/ServerSentEvents");

    //默认支持message事件
    source.onmessage = function (event) {
        console.log(source.readyState);
        console.log(event);
    };

实例解析:
  创建一个新的 EventSource 对象,然后规定发送更新的页面的 URL(本例中是 "demo_sse.php"),参数url就是服务器网址,必须与当前网页的网址在同一个网域(domain),而且协议和端口都必须相同
  每接收到一次更新,就会发生 onmessage 事件

 

检测 Server-Sent 事件支持
以下实例,我们编写了一段额外的代码来检测服务器发送事件的浏览器支持情况:

if(!!EventSource && typeof(EventSource)!=="undefined")
{
    // 浏览器支持 Server-Sent
    // 一些代码.....
}
else
{
    // 浏览器不支持 Server-Sent..
}

服务器端代码实例
为了让上面的例子可以运行,您还需要能够发送数据更新的服务器(比如 PHP、ASP、ASP.NET、Java)。
服务器端事件流的语法是非常简单的。你需要把 "Content-Type" 报头设置为 "text/event-stream"。现在,您可以开始发送事件流了。
我只会C#,所以用 ASP.NET的MVC 里面的ApiController写了个最简单的服务器端:

    public class MyAPIController : ApiController
    {
        /// <summary>
        /// ...api/MyAPI/ServerSentEvents
        /// </summary>
        /// <returns></returns>
        [HttpGet, HttpPost]
        public Task<HttpResponseMessage> ServerSentEvents()
        {
            //Response.ContentType = "text/event-stream"
            //Response.Expires = -1
            //Response.Write("data: " & now())
            //Response.Flush()

            string data = "id: 123456nevent: messagendata: 666nn";

            HttpResponseMessage response = new HttpResponseMessage
            {
                //注意:ContentType = "text/event-stream"
                Content = new StringContent(data, Encoding.GetEncoding("UTF-8"), "text/event-stream")
            };

            return Task.FromResult(response);
        }
    }

代码解释:
  把报头 "Content-Type" 设置为 "text/event-stream"
威尼斯城vnsc登入平台,  规定不对页面进行缓存
  输出发送日期(始终以 "data: " 开头)
  向网页刷新输出数据

 

EventSource 对象

新生成的EventSource实例对象,有一个readyState属性,表明连接所处的状态。

source.readyState
它可以取以下值:

  0,相当于常量EventSource.CONNECTING,表示连接还未建立,或者连接断线。

  1,相当于常量EventSource.OPEN,表示连接已经建立,可以接受数据。

  2,相当于常量EventSource.CLOSED,表示连接已断,且不会重连。

 

在上面的例子中,我们使用 onmessage 事件来获取消息。不过还可以使用其他事件:
事件    描述
onopen   当通往服务器的连接被打开
onmessage 当接收到消息
onerror   当发生错误

 

open事件

连接一旦建立,就会触发open事件,可以定义相应的回调函数。

source.onopen = function(event) {
// handle open event
};

// 或者

source.addEventListener("open", function(event) {
// handle open event
}, false);
message事件

收到数据就会触发message事件。

source.onmessage = function(event) {
var data = event.data;
var origin = event.origin;
var lastEventId = event.lastEventId;
// handle message
};

// 或者

source.addEventListener("message", function(event) {
var data = event.data;
var origin = event.origin;
var lastEventId = event.lastEventId;
// handle message
}, false);
参数对象event有如下属性:

data:服务器端传回的数据(文本格式)。

origin: 服务器端URL的域名部分,即协议、域名和端口。

lastEventId:数据的编号,由服务器端发送。如果没有编号,这个属性为空。

error事件

如果发生通信错误(比如连接中断),就会触发error事件。

source.onerror = function(event) {
// handle error event
};

// 或者

source.addEventListener("error", function(event) {
// handle error event
}, false);
自定义事件

服务器可以与浏览器约定自定义事件。这种情况下,发送回来的数据不会触发message事件。

source.addEventListener("foo", function(event) {
var data = event.data;
var origin = event.origin;
var lastEventId = event.lastEventId;
// handle message
}, false);
上面代码表示,浏览器对foo事件进行监听。

close方法

close方法用于关闭连接。

source.close();
数据格式
概述

服务器端发送的数据的HTTP头信息如下:

Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
后面的行都是如下格式:

本文由威尼斯城vnsc登入平台发布于网络信息,转载请注明出处:Server-Sent Events(HTML5 服务器发送事件),server-

关键词:

  • 上一篇:没有了
  • 下一篇:没有了