server-sent events (简称SSE)

1、SSE 的本质

严格来说 http 无法向客户端主动发起推送信息,有一种变通的方法,就是服务器向客户端说明要发送的是流信息,也就是说,发送的不是一次性的数据包,而是一个数据流会连续不断的发送过来,这时,客户端不会关闭连接,会一直等着服务器发过来的新的数据流,SSE 就是利用这种机制,使用流信息向浏览器推送信息。它基于 HTTP 协议

2、SSE 的特点

SSE 使用 HTTP 协议,现有的服务器软件都支持。WebSocket 是一个独立协议。
SSE 属于轻量级,使用简单;WebSocket 协议相对复杂。
SSE 默认支持断线重连,WebSocket 需要自己实现。
SSE 一般只用来传送文本,二进制数据需要编码后传送,WebSocket 默认支持传送二进制数据。
SSE 支持自定义发送的消息类型。

3、客户端API

3.1、EventSource 对象

使用 SSE 时,浏览器首先生成一个EventSource实例,向服务器发起连接。
var source = new EventSource(url);
上面的url可以与当前网址同域,也可以跨域。跨域时,可以指定第二个参数,打开withCredentials属性,表示是否一起发送 Cookie。

var source = new EventSource(url, { withCredentials: true });

EventSource实例的readyState属性,表明连接的当前状态。该属性只读,可以取以下值。
0:相当于常量EventSource.CONNECTING,表示连接还未建立,或者断线正在重连。1:相当于常量EventSource.OPEN,表示连接已经建立,可以接受数据。2:相当于常量EventSource.CLOSED,表示连接已断,且不会重连。

3.2 基本用法

连接一旦建立,就会触发open方法,可以在onopen属性定义回调函数

source.onopen = function (event) {// ...
};// 另一种写法
source.addEventListener('open', function (event) {// ...
}, false);
//客户端收到服务器发来的数据,就会触发message事件,可以在onmessage属性的回调函数。
source.onmessage = function (event) {var data = event.data;// handle message
};// 另一种写法
source.addEventListener('message', function (event) {var data = event.data;// handle message
}, false);

上面代码中,事件对象的data属性就是服务器端传回的数据(文本格式)。如果发生通信错误(比如连接中断),就会触发error事件,可以在onerror属性定义回调函数。

source.onerror = function (event) {// handle error event
};// 另一种写法
source.addEventListener('error', function (event) {// handle error event
}, false);
close方法用于关闭 SSE 连接
source.close();

3.3自定义事件

触发自定义事件就不会触发message事件

source.addEventListener('foo', function (event) {var data = event.data;// handle message
}, false);

4、服务器实现

4.1、数据格式

服务器向浏览器发送的数据必须是UTF-8 格式的数据,据有如下的http头部信息

Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive

4.2 data格式
数据内容由data字段表示
数据内容用data字段表示。

data: message\n\n

4.3、id字段

数据标识符用id字段表示,相当于每一条数据的编号。

id: msg1\n
data: message\n\n

浏览器用lastEventId属性读取这个值。一旦连接断线,浏览器会发送一个 HTTP 头,里面包含一个特殊的Last-Event-ID头信息,将这个值发送回来,用来帮助服务器端重建连接。因此,这个头信息可以被视为一种同步机制。

4.4、event字段

event字段表示自定义的事件类型,默认是message事件。浏览器可以用addEventListener()监听该事件。

event: foo\n
data: a foo event\n\ndata: an unnamed event\n\nevent: bar\n
data: a bar event\n\n

上面的代码创造了三条信息。第一条的名字是foo,触发浏览器的foo事件;第二条未取名,表示默认类型,触发浏览器的message事件;第三条是bar,触发浏览器的bar事件。
下面是另一个例子。

event: userconnect
data: {"username": "bobby", "time": "02:33:48"}event: usermessage
data: {"username": "bobby", "time": "02:34:11", "text": "Hi everyone."}event: userdisconnect
data: {"username": "bobby", "time": "02:34:23"}event: usermessage
data: {"username": "sean", "time": "02:34:36", "text": "Bye, bobby."}

4.5、retry字段

服务器可以用retry字段,指定浏览器发起重连的时间间隔
retry: 10000\n

两种情况会导致浏览器重新发起连接:一种是时间间隔到期,二是由于网络错误等原因,导致连接出错。

5、Node 服务器示例

SSE 要求服务器与浏览器保持连接。对于不同的服务器软件来说,所消耗的资源是不一样的。Apache 服务器,每个连接就是一个线程,如果要维持大量连接,势必要消耗大量资源。Node 则是所有连接都使用同一个线程,因此消耗的资源会小得多,但是这要求每个连接不能包含很耗时的操作,比如磁盘的 IO 读写

var http = require("http");http.createServer(function (req, res) {var fileName = "." + req.url;if (fileName === "./stream") {res.writeHead(200, {"Content-Type":"text/event-stream","Cache-Control":"no-cache","Connection":"keep-alive","Access-Control-Allow-Origin": '*',});res.write("retry: 10000\n");res.write("event: connecttime\n");res.write("data: " + (new Date()) + "\n\n");res.write("data: " + (new Date()) + "\n\n");interval = setInterval(function () {res.write("data: " + (new Date()) + "\n\n");}, 1000);req.connection.addListener("close", function () {clearInterval(interval);}, false);}
}).listen(8844, "127.0.0.1");

server-sent events相关推荐

  1. SQL Server Extended Events 进阶 3:使用Extended Events UI

    开始采用Extended Events 最大的阻碍之一是需要使用Xquery和XML知识用来分析数据.创建和运行会话可以用T-SQL完成,但是无论使用什么目标,数据都会被转换为XML.这个限制在SQL ...

  2. SQL Server Extended Events (扩展事件)

    To be continue 转载于:https://www.cnblogs.com/ziqiumeng/p/10829338.html

  3. sql server死锁_如何使用扩展事件和SQL Server代理自动执行SQL Server死锁收集过程

    sql server死锁 介绍 (Introduction) This article is the last one of a series in which we discussed how to ...

  4. 了解SQL Server审核

    介绍 (Introduction) With the advent of the Information Era, data is being collected on a massive scale ...

  5. SQL Server审核最佳做法

    In this article on SQL Server Auditing Best practices, we will show the best practices that should b ...

  6. sql server死锁_如何报告SQL Server死锁事件

    sql server死锁 介绍 (Introduction) In the previous article entitled "What are SQL Server deadlocks ...

  7. sql活动监视器 死锁_监视SQL Server死锁–简单方法

    sql活动监视器 死锁 SQL Server is a very powerful tool and wherever I go, I see the tool being way much unde ...

  8. apexsql使用方法_使用ApexSQL审核执行SQL Server审核

    apexsql使用方法 This is the last article, but not least, in the SQL Server Audit series. In this series ...

  9. SQL Server审核功能–发现和体系结构

    介绍 (Introduction) Intended audience 目标听众 This document is intended for database administrators who p ...

  10. sql server调试_使用SQL Server扩展事件来调试应用程序

    sql server调试 介绍 (Introduction) Often enough, multilayer software has bugs. SQL Server Extended Event ...

最新文章

  1. php mysql管理_MySQL 连接与管理
  2. Spring框架的事务管理的基本概念
  3. 内存位置访问无效 midas.dll_java并发之内存模型
  4. Nginx配置HTTP2.0
  5. python包的使用(一)——WordCloud词云
  6. Winfrom 定时锁屏
  7. uint32 t java_数据类型 -- uint32_t 类型
  8. static关键字的用法
  9. 《王者荣耀》手游产品分析报告:崛起的王者荣耀,胜负就是这么简单!
  10. 安装mysql staring server 失败 已经成功决解。
  11. 嵌入式方向如何转行?
  12. Unity3D 实现背包系统
  13. 中文信息处理实验2——基于词表的分词
  14. c语言猜12生肖一种,12生肖2017年运程完整版十二生肖中最老的是哪个生肖_脑筋急转弯_算......
  15. 深入分析:代理游戏真的可以赚钱吗?
  16. Linux服务器域名配置
  17. 三维空间中平面的法向量计算
  18. JAVA工具类(13)---图片上传工具类
  19. r语言 python 股票_python r语言 股票!如何用python写出爬虫?
  20. php获取当前网页连接失败,获取连接失败:php_network_getaddresses:getaddrinfo failed:名称或服务未知...

热门文章

  1. IMDB-WIKI人脸属性数据集解析,dob matlab序列号转为出生日期
  2. 读《DOOM启示录》随想
  3. Linux netstat命令详解
  4. 锐捷 重启计算机,关于锐捷客户端重安装后要求反覆重启的解决办法
  5. 《土豆荣耀》重构笔记(七)控制角色移动并添加音效
  6. NLPIR系统的中文语义分析模式介绍
  7. 机敏问答[博弈][0] #20210628
  8. 启明星 微信版 会议室预定系统
  9. Git使用教程:最详细、最傻瓜、最浅显、真正手把手教!
  10. 冒险岛java_079src 冒险岛079服务端源码,解压出来 直接导入到java改成即可 Develop 243万源代码下载- www.pudn.com...