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. HDU - 5788 Level Up(主席树+dfs序+树状数组)
  2. Bootstrap中实现图片圆角效果
  3. LeetCode 1688. 比赛中的配对次数(模拟)
  4. 理解 JavaScript 作用域
  5. 第4阶段——制作根文件系统之分析init_post()如何启动第1个程序(1)
  6. html5 jpg转webp格式转换,JPEG和WebP格式图片的差别
  7. 【图像处理】空间滤波、中值滤波(Spatial Filtering and Median Filtering)
  8. 汇编语言编写Hello World
  9. android-gradle-plugin3.0.1源码分析
  10. 现实世界的Windows Azure:采访Definition 6首席技术官Paul Hernacki
  11. editormd html 转义,Markdown(editormd)语法解析成HTML
  12. AQL学习笔记(二)--文档的创建
  13. Cadence 16.6 Allegro中如何设置多层板的每一层的单端信号的线宽以保证50Ω阻抗?
  14. Error with Permissions-Policy header: Origin trial controlled feature not enabled: ‘interest-cohort‘
  15. [luogu#2019/03/10模拟赛][LnOI2019]长脖子鹿省选模拟赛赛后总结
  16. css3绘制八卦图及动画效果
  17. Python调用ffmpeg对视频抽帧
  18. 解决ios端 橡皮筋
  19. 给JAVA初学者的建议
  20. 20 致远OA场景-流程事件

热门文章

  1. 计算机中官方文档阅读方法,利用Word阅读电子文档-word技巧-电脑技巧收藏家
  2. First Happy Work :)
  3. OpenCV-基于自定义色条实现灰度图上色
  4. Asp.net+Vue2构建简单记账WebApp之六(vue.js构建记账统计页面)
  5. 卖橘子的计算器:写一段代码,提示用户输入橘子的价格,和重量,最后计算出应该支付的金额!(不需要校验数据,都传入数字就可以了。)
  6. 嵌入式开发学习的几种线路图方向
  7. 腾讯云网站备案咨询:主体信息相关问题解答
  8. 巨人的崛起 Android操作系统发展历程
  9. DDD学习笔记 - 总结篇
  10. (三十)股指期货的交叉套保