文档章节

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

一点灵犀
 一点灵犀
发布于 2015/04/13 14:52
字数 624
阅读 249
收藏 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的应答即可。

参考:

© 著作权归作者所有

共有 人打赏支持
一点灵犀

一点灵犀

粉丝 10
博文 52
码字总数 15202
作品 1
深圳
程序员
分布式日志收集系统Flume

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

林中漫步
2016/05/31
130
0
flume的基本概念,数据流模型

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

张欢19933
2016/01/20
99
0
详解如何实现在线聊天系统中的实时消息获取

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

中间件小哥
08/08
0
0
Server-Sent Events

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

Bery
2017/10/20
0
0
使用Flume将日志导入OSS

前言 Apache Flume是一个高可用、高可靠的分布式日志采集、聚合与传输的系统。它基于流式的数据传输,架构简单、灵活。它简单可扩展的模型,也适合在线的数据分析。 上图是它的简单数据流模型...

冷月_wjh
08/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周日乱弹 —— 小心着凉 @红薯

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @莱布妮子:5.33起,其声呜呜然,如怨如慕,如泣如诉。余音袅袅,不绝如缕。分享Arch Enemy的单曲《Bridge Of Destiny (2009)》 《Bridge Of...

小小编辑
今天
250
4
what f,,

anlve
今天
9
0
初级开发-编程题

` public static void main(String[] args) { System.out.println(changeStrToUpperCase("user_name_abc")); System.out.println(changeStrToLowerCase(changeStrToUpperCase("user_name_abc......

小池仔
今天
15
0
现场看路演了!

HiBlock
昨天
23
0
Rabbit MQ基本概念介绍

RabbitMQ介绍 • RabbitMQ是一个消息中间件,是一个很好用的消息队列框架。 • ConnectionFactory、Connection、Channel都是RabbitMQ对外提供的API中最基本的对象。Connection是RabbitMQ的s...

寰宇01
昨天
18
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部