SSE(Server-Sent Events):通俗解释起来就是一种基于HTTP的,以流的形式由服务端持续向客户端发送数据的技术

应用场景

由于HTTP是无状态的传输协议,每次请求需由客户端向服务端建立连接,HTTPS还需要交换秘钥,所以一次请求,建立连接的过程占了很大比例

在http1.1中(1.0也有但未写入标准),虽然增加了keep-alive来保持和服务器的长连接,省去了很多建立连接的过程,但通信过程仍然是应答式1:1的方式,也就是想要获得数据,就必须先发送一个request才能得到一个response,所以在实时监控、推送、视频直播等实时性较高或者带宽利用较苛刻的场景,仍然不是很合适

SSE技术由于能保持连接,并持续接收服务端的数据,所以弥补了这一缺点,与其他类似技术方案相比,短轮询、Coment、WebSocket,在大多数时候,SSE仍然是最好的选择

各技术方案的优缺点

短轮询

短轮询很简单,即客户端定时的向服务端发送请求,如果服务端有数据返回,则返回数据,否则返回空数据

优点:实现简单

缺点:如果想实时性好,则必须轮询间隔短,但会有大量的请求是无效的(返回空数据),如果轮询间隔长,则实时性不好,数据到达客户端的延时最大会趋近于轮询间隔

Coment:一种HACK技术

以即时通信为代表的web应用程序对数据的Low Latency要求,传统的基于轮询的方式已经无法满足,而且也会带来不好的用户体验。于是一种基于http长连接的“服务器推”技术便被hack出来。这种技术被命名为Comet,这个术语由Dojo Toolkit 的项目主管Alex Russell在博文Comet: Low Latency Data for the Browser首次提出,并沿用下来。

Coment技术有两种实现,分别是长轮询(long-polling)和基于 Iframe 及 htmlfile 的流(http streaming)方式

1.长轮询(long-polling)

浏览器发出ajax 请求,服务器端接收到请求后,会阻塞请求直到有数据或者超时才返回,浏览器JS在处理请求返回信息(超时或有效数据)后再次发出请求,重新建立连接。在此期间服务器端可能已经有新的数据到达,服务器会选择把数据保存,直到重新建立连接,浏览器会把所有数据一次性取回。

优缺点:这种技术没有明显的优缺点,如果非要说,就是需要额外的框架支持吧,且在之前服务端异步编程支持程度并不高的时候,(例如java的servlet3.0之前),后端也需要额外的框架支持

2.基于 Iframe 及 htmlfile 的流

Iframe是html标记,这个标记的src属性会保持对指定服务器的长连接请求,服务器端则可以不停地返回数据,相对于第一种方式,这种方式跟传统的服务器推则更接近。

在第一种方式中,浏览器在收到数据后会直接调用JS回调函数,但是这种方式该如何响应数据呢?可以通过在返回数据中嵌入JS脚本的方式,如“”,服务器端将返回的数据作为回调函数的参数,浏览器在收到数据后就会执行这段JS脚本。

缺点:IE、Morzilla Firefox 下端的进度栏都会显示加载没有完成,而且 IE 上方的图标会不停的转动,表示加载正在进行。

WebSocket

类似TCP socket,参考WebSocket详解

优点:双工通信

缺点:需专门定义数据协议,解析数据流,且部分服务器支持不完善,后台例如java spring boot 2.1.2 仅支持websocket 1.0(最高已达1.3)

SSE

优点:开发简单,和传统的http开发几乎无任何差别,客户端开发简单,有标准支持(EventSource)

缺点:和websocket相比,只能单工通信,建立连接后,只能由服务端发往客户端,且占用一个连接,如需客户端向服务端通信,需额外打开一个连接

其他

在基于spring的开发中,可以使用SseEmitter类进行通信

@GetMapping(value = "/watch", produces = MediaType.TEXT_EVENT_STREAM_VALUE)

public synchronized SseEmitter watch(HttpServletRequest request, @RequestParam("point") String point) throws Exception {

final HttpSession session = request.getSession();

//此处超时时间优先级高于servlet容器的request timeout,PS:此超时时间固定,无法通过心跳等其他手段保持连接,超时后 浏览器端默认会重新连接,但SeeEmitter无法复用

SseEmitter emitter = new SseEmitter(300 * 1000L);

String key = String.format("watch:%s", point);

WatchConsumer consumer = new WatchConsumer<>(client, emitter, point);

if (this.client.watch(point, consumer)) {

emitter.onCompletion(() -> session.removeAttribute(key));

emitter.onTimeout(() -> session.removeAttribute(key));

emitter.onError(throwable -> {

throwable.printStackTrace();

session.removeAttribute(key);

});

session.setAttribute(key, consumer);

}

return emitter;

}

也可以利用WebFlux,

@GetMapping("/stream-sse")

public Flux> streamEvents() {

return Flux.interval(Duration.ofSeconds(1))

.map(sequence -> ServerSentEvent. builder()

.id(String.valueOf(sequence))

.event("periodic-event")

.data("SSE - " + LocalTime.now().toString())

.build());

}

但相比之下SseEmitter有OnTimeout和OnCompletion等事件,更加灵活

PS:由于浏览器对于同一个domain,有并发数限制,例如chrome最大是6,长连接会持续性的占用一个连接,同时会占用一个服务器端的一个连接

sse java_SSE详解相关推荐

  1. 【转】WebSocket详解(一):初步认识WebSocket技术

    1.前言 HTML5规范在传统的web交互基础上为我们带来了众多的新特性,随着web技术被广泛用于web APP的开发,这些新特性得以推广和使用,而websocket作为一种新的web通信技术具有巨大 ...

  2. 新手入门:史上最全Web端即时通讯技术原理详解

    前言 有关IM(InstantMessaging)聊天应用(如:微信,QQ).消息推送技术(如:现今移动端APP标配的消息推送模块)等即时通讯应用场景下,大多数都是桌面应用程序或者native应用较为 ...

  3. WebSocket详解(一):初步认识WebSocket技术

    WebSocket详解(一):初步认识WebSocket技术 1.前言 HTML5规范在传统的web交互基础上为我们带来了众多的新特性,随着web技术被广泛用于web APP的开发,这些新特性得以推广 ...

  4. P2P技术详解(一):NAT详解——详细原理、P2P简介(转)

    这是一篇介绍NAT技术要点的精华文章,来自华3通信官方资料库,文中对NAT技术原理的介绍很全面也很权威,对网络应用的应用层开发人员而言有很高的参考价值. <P2P技术详解>系列文章 ➊ 本 ...

  5. 015. P2P技术详解(一):NAT详解——详细原理、P2P简介

    http://www.52im.net/thread-50-1-1.html 这是一篇介绍NAT技术要点的精华文章,来自华3通信官方资料库,文中对NAT技术原理的介绍很全面也很权威,对网络应用的应用层 ...

  6. (转)理论经典:TCP协议的3次握手与4次挥手过程详解

    摘要: 本文将分别讲解经典的TCP协议建立连接(所谓的"3次握手")和断开连接(所谓的"4次挥手")的过程. 1.前言 尽管TCP和UDP都使用相同的网络层(I ...

  7. 新手入门贴:史上最全Web端即时通讯技术原理详解

    前言 有关IM(InstantMessaging)聊天应用(如:微信,QQ).消息推送技术(如:现今移动端APP标配的消息推送模块)等即时通讯应用场景下,大多数都是桌面应用程序或者native应用较为 ...

  8. Web端即时通讯技术原理详解

    Web端即时通讯技术原理详解 前言 在web端的IM即时通讯应用,由于浏览器的兼容性以及其固有的"客户端请求服务器处理并响应"的C/S通信模型,造成了要在浏览器中实现一个兼容性较好 ...

  9. Linux中/proc目录下文件详解

    Linux中/proc目录下文件详解(一) 声明:可以自由转载本文,但请务必保留本文的完整性. 作者:张子坚 email:zhangzijian@163.com 说明:本文所涉及示例均在fedora ...

最新文章

  1. C#最基本的小说爬虫
  2. 文件服务器的配置与管理(2) 实现软RAID
  3. 因OpenCV版本不一致所引发的报错
  4. router锚点和html锚点,hash模式下Vue-router页面返回锚点(scroll behavior)实现
  5. Android studio gradle 无法获取 pom文件
  6. SpringBoot 使用 log4j2
  7. GP学习(二)—Executing tools and Accesubg licensing0
  8. 轻量版 markdown博客_如何快速搭建自己的博客平台
  9. Hadoop之自定义数据类型
  10. Cocos Creator 原生安卓改包名+AS运行到真机apk被slice处理而失败
  11. 【独家】阿里云罗庆超:对象存储 OSS 海量数据管理和应用最佳实践
  12. 蓝桥杯c语言b组试题及答案,2014蓝桥杯C语言本科B组预赛试题
  13. android web sevice,Web Service在Android开发中的应用研究
  14. Win10版本怎么转换?小编教你一键切换Windows版本
  15. JAVA高效批量插入数据到数据库demo
  16. 神经网络权重是什么意思,神经网络权重调整方法
  17. AJP:22q11.2缺失综合征青少年gamma频带反应和远程通信中断的异常发育模式
  18. 沉船会有什么_神秘沉船,惊人宝藏,尘封历史,这部纪录片的结尾却让人难以置信...
  19. 保障4-0601任务打卡
  20. [MachineLearning]模型评估与模型选择

热门文章

  1. expect java,Expect 使用详解
  2. 关于linux内核中jiffies和jiffies_64解析
  3. VSCode 根据需要设置自动补全(代码联想)类别
  4. pytest fixture简介
  5. 鸿蒙哪些机型可以用,鸿蒙系统可以在哪些手机上使用 鸿蒙系统升级名单
  6. Cell Biolabs丨艾美捷——细胞选择 24孔细胞共培养系统
  7. Presto客户端报错:Query failed (#20200815_082938_00004_a5yxe) in tmall-presto: Catalog hive does not exis
  8. 第7章 事件驱动编程:编写一个视频游戏
  9. 免费的IP地址查询API接口
  10. php编写六十甲子纳音表,六十花甲子纳音表