WebSocket,Server-Sent Events:服务器发送事件,使用长链接进行通讯

本文详细介绍了WebSocket和Server-Sent Events(SSE)两种服务器向浏览器推送数据的技术。WebSocket提供双向通信,适合需要频繁交互的场景,而SSE是单向推送,更轻量级,适合简单的实时更新。文中通过实例代码展示了如何在客户端和服务器端实现WebSocket和SSE,同时对比了两者在实现和使用上的区别,包括数据格式、重连机制、资源消耗等方面,并提供了实际应用场景的案例分析。
摘要由CSDN通过智能技术生成

转自利用WebSocket和EventSource实现服务端推送

概述

传统的网页都是浏览器向服务器“查询”数据,但是很多场合,最有效的方式是服务器向浏览器“发送”数据。比如,webpack的HRM,每当收到新的电子邮件,服务器就向浏览器发送一个“通知”,这要比浏览器按时向服务器查询(polling)更有效率。

服务器发送事件(Server-Sent Events,简称SSE)就是为了解决这个问题,而提出的一种新API,部署在EventSource对象上。目前,除了IE,其他主流浏览器都支持。

简单说,所谓SSE,就是浏览器向服务器发送一个HTTP请求,然后服务器不断单向地向浏览器推送“信息”(message)。这种信息在格式上很简单,就是“信息”加上前缀“data: ”,然后以“\n\n”结尾。

$ curl http://example.com/dates
data: 1394572346452

data: 1394572347457

data: 1394572348463
复制代码

SSE与WebSocket有相似功能,都是用来建立浏览器与服务器之间的通信渠道。两者的区别在于:

  • WebSocket是全双工通道,可以双向通信,功能更强;SSE是单向通道,只能服务器向浏览器端发送。

  • WebSocket是一个新的协议,需要服务器端支持;SSE则是部署在HTTP协议之上的,现有的服务器软件都支持。

  • SSE是一个轻量级协议,相对简单;WebSocket是一种较重的协议,相对复杂。

  • SSE默认支持断线重连,WebSocket则需要额外部署。

  • SSE支持自定义发送的数据类型。

从上面的比较可以看出,两者各有特点,适合不同的场合。

客户端代码

概述

首先,使用下面的代码,检测浏览器是否支持SSE。

if (!!window.EventSource) {
  // ...
}
复制代码

然后,部署SSE大概如下。

var source = new EventSource('/dates');

source.onmessage = function(e){
  console.log(e.data);
};

// 或者

source.addEventListener('message', function(e){})
复制代码

建立连接

首先,浏览器向服务器发起连接,生成一个EventSource的实例对象。

var source = new EventSource(url);
复制代码

参数url就是服务器网址,必须与当前网页的网址在同一个网域(domain),而且协议和端口都必须相同。

下面是一个建立连接的实例。

if (!!window.EventSource) {
  var source = new EventSource('http://127.0.0.1/sses/');
}
复制代码

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

source.readyState
复制代码

它可以取以下值:

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

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

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

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
复制代码

后面的行都是如下格式:

field: value\n
复制代码

field可以取四个值:“data”, “event”, “id”, or “retry”,也就是说有四类头信息。每次HTTP通信可以包含这四类头信息中的一类或多类。\n代表换行符。

以冒号开头的行,表示注释。通常,服务器每隔一段时间就会向浏览器发送一个注释,保持连接不中断。

: This is a comment
复制代码

下面是一些例子。

: this is a test stream\n\n

data: some text\n\n

data: another message\n
data: with two lines \n\n
复制代码

data:数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值