文档章节

(翻译)H5数据流消息推送机制Event Source

一点灵犀
 一点灵犀
发布于 2015/04/13 14:52
字数 624
阅读 1K
收藏 2

关于数据推送,传统方法是前端(不)定时发送HTTP请求进行轮询。但这种方式非常的损耗服务器资源,不适合访问量高的情况。

目前H5提供两种方式:Server-Sent EventsWebSockets。 前者只是服务器单向推送数据,易于使用,且浏览器会自动重连;后者支持交互,但实现较复杂。 本文只介绍前一种方案。

###JavaScript API###

var source = new EventSource(URL); // 注意跨域问题
source.addEventListener('message', function(e) {
  console.log(e.data);
}, false);
source.addEventListener('open', function(e) {
  // Connection was opened.
}, false);
source.addEventListener('error', function(e) {
  if (e.readyState == EventSource.CLOSED) {
    // Connection was closed.
  }
}, false);

连接成功后,浏览器每隔3秒会自动重连,收到的数据通过message事件响应。

###Event Stream数据格式###

服务器正常情况下返回一个Content-Type类型为text/event-stream的纯文本内容。

最简单形如:data:str\n\n,即以data:起头,两个换行符结尾。这样e.data就是str

如果要返回多行文本,依样增加,但要注意前面只添加一个换行符,最后一个则是两个:

data: first line\n
data: second line\n\n

如果要返回JSON格式的内容呢?依法炮制:

data: {\n
data: "msg": "hello world",\n
data: "id": 12345\n
data: }\n\n

为了标记响应数据,可以增加一段id: 12345\n,id值可以通过message响应事件的e.lastEventId属性读取。同时,浏览器发送请求时,其消息头会自动带上这个数值(参数名为Last-Event-ID)。

有时候数据更新比较缓慢,因此设置WEB延迟一段事件再发送请求,方法是增加一个retry属性:

retry: 10000\n
data: hello world\n\n

这样下一次请求会延长到10秒。仅一次有效。

甚至,你还可以自定义添加事件名称(默认是message):

// 服务器端
data: {"msg": "First message"}\n\n
event: userlogon\n
data: {"username": "John123"}\n\n
event: update\n
data: {"username": "John123", "emotion": "happy"}\n\n
// WEB端
source.addEventListener('message', function(e) {
  var data = JSON.parse(e.data);
  console.log(data.msg);
}, false);

source.addEventListener('userlogon', function(e) {
  var data = JSON.parse(e.data);
  console.log('User login:' + data.username);
}, false);

source.addEventListener('update', function(e) {
  var data = JSON.parse(e.data);
  console.log(data.username + ' is now ' + data.emotion);
}, false);

###取消或中断连接###

在WEB端,通过source.close()关闭连接。

在服务器端,返回一个Content-Type非text/event-stream或HTTP status不为200的应答即可。

参考:

© 著作权归作者所有

一点灵犀

一点灵犀

粉丝 11
博文 53
码字总数 15777
作品 1
深圳
程序员
私信 提问
加载中

评论(0)

[白话解析] Flink的Watermark机制

[白话解析] Flink的Watermark机制 0x00 摘要 对于Flink来说,Watermark是个很难绕过去的概念。本文将从整体的思路上来说,运用感性直觉的思考来帮大家梳理Watermark概念。 0x01 问题 关于Wat...

osc_ymlf86ez
04/16
7
0
分布式日志收集系统Flume

Flume简介 Flume是一个分布式的、高可用的海量日志采集系统。它支持对日志数据的发送方、接收方进行定义,可将多种来源的日志数据写到指定的接收方,如:文本、HDFS、Hbase等。 我认为Flume...

林中漫步
2016/05/31
208
0
Server-Sent Events

简介 服务器向客户端推送数据,有很多解决方案。除了“轮询” 和 WebSocket,HTML 5 还提供了 Server-Sent Events(以下简称 SSE)。 一般来说,HTTP 协议只能客户端向服务器发起请求,服务器...

Bery
2017/10/20
104
0
详解如何实现在线聊天系统中的实时消息获取

序言 传统web浏览器应用采用客户端主动请求方式,只有在收到浏览器请求时服务端才返回消息,这种模式已经不能满足日益多样化的web应用需求,例如: 在线聊天系统:需要实时获取聊天消息。 实...

中间件小哥
2018/08/08
64
0
flume的基本概念,数据流模型

1.flume的基本概念 本文中所有与flume相关术语都采用斜体英文表示,这些术语的含义如下所示。 flume 一个可靠的,分布式的,用于采集,聚合,传输海量日志数据的系统。 Web Server 一个产生 ...

张欢19933
2016/01/20
155
0

没有更多内容

加载失败,请刷新页面

加载更多

一言难尽,Jpa这个功能差点让我丢了工作

故事背景 前阵子,有位朋友在微信上问我数据被删了能不能恢复,我问了下原因,居然是因为一个配置项惹的祸。 故事细节 在 Spring Boot 中使用 jpa 来操作数据库,jpa 就不做详细的介绍了,相...

osc_axe50nd6
4分钟前
0
0
Link Cut Tree

//知识点 : LCT /*By:Luckyblock*/#include <cstdio>#include <ctype.h>#include <algorithm>#define ls (t[x].son[0])#define rs (t[x].son[1])const int kMaxn = 1e5 + 10;//===......

osc_q5urtsdm
5分钟前
11
0
【问题】Could not locate PropertySource and the fail fast property is set, failing

这是我遇到的问题 Could not locate PropertySource and the fail fast property is set, failing springcloud的其他服务读取不了配置中心得配置文件出错,原因是配置中心的一个配置文件有s...

osc_z9jr2tjo
7分钟前
5
0
Angular SPA基于Ocelot API网关与IdentityServer4的身份认证与授权(四)

在上一讲中,我们已经完成了一个完整的案例,在这个案例中,我们可以通过Angular单页面应用(SPA)进行登录,然后通过后端的Ocelot API网关整合IdentityServer4完成身份认证。在本讲中,我们...

osc_doeya1ck
8分钟前
11
0
[推荐]大量 Blazor 学习资源(一)

前言 / Introduction Blazor 是什么? Blazor 允许您使用 C# 而不是 JavaScript 构建交互式 Web UI。 Blazor 应用由使用 C#、HTML 和 CSS 实现的可重用 Web UI 组件组成。客户端和服务器代码...

osc_3r4js8qy
9分钟前
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部