文章目录 [隐藏]

  • SSE(服务器推送事件)的介绍、问题及解决

SSE(服务器推送事件)的介绍、问题及解决


seymour1996

关注

2018.01.13 22:16*
字数 988
阅读 852评论 2喜欢 5

介绍

所谓SSE(Sever-Sent Event),就是浏览器向服务器发送一个HTTP请求,保持长连接,服务器不断单向地向浏览器推送“信息”(message),这么做是为了节约网络资源,不用一直发请求,建立新连接。

  • 长轮询:客户端向服务器发送Ajax请求,服务器接到请求后保持连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求。

    长轮询

  • 长连接:保持长时间的连接,服务器发送数据后,连接不关闭,下次有新数据时仍然用此连接发送

    长连接

应用场景

  • 实时更新数据:比如网页上股票价格的更新,假设每秒钟要更新一次,如果用轮询的方法那我们每秒钟就要发送一次http请求,而用SSE,客户端发了一次请求以后,服务器就不断推送消息,客户端只需接收就可以了。
  • 新消息推送:比如有新的通知、新的订单就能第一时间推送给客户端

评价

  • 优点:SSE和WebSocket相比,最大的优势是便利,服务端不需要其他的类库,开发难度较低,SSE和轮询相比它不用处理很多请求,不用每次建立新连接,延迟较低。
  • 缺点:如果客户端有很多,那就要保持很多长连接,这会占用服务器大量内存和连接数

我们先来看一下《颠覆者》中的例子:
public @ResponseBody String push(){Random r = new Random();try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "data:Testing 1,2,3" + r.nextInt() +"nn";
}

问题1:长连接

这里return之后连接不就断了吗?怎么推送消息?

测试结果:

连接不停地打开关闭

多个请求

问题解决:

我们可以看到每个请求只返回了一次数据,服务器每次发完数据就断开了连接,但SSE默认会自动重连,所以客户端不断地重连(重新发请求),但这样不是类似ajax长轮询吗?作者可能对SSE存在误解了,这里有点大材小用。

改进方案:

我们发送消息时不用return,因为一旦return这个连接就断开了,我们应该改把数据写到response里,并用flush()方法输出。

public void push(HttpServletResponse response) {
response.setContentType("text/event-stream");
response.setCharacterEncoding("utf-8");while (true) {Random r = new Random();try {
Thread.sleep(1000);
PrintWriter pw=response.getWriter();
pw.write("data:Testing 1,2,3" + r.nextInt() + "nn");
pw.flush();
} catch (Exception e) {e.printStackTrace();}
}

实验结果:

保持长连接

只有一次请求

这样就实现了客户端只发送一次请求,服务器不断地单向推送消息,保持长连接。


问题2:如何跳出循环

我们写了while(true)让它保持连接,不停地推送数据,但是浏览器关闭时却没有抛出异常,这里很奇怪为什么连接关闭了还能执行flush()方法?这样的话浏览器关闭了,服务器却还在执行这个循环,这种情况显然是不允许的。

问题解决:

查阅了PrinterWriter源码后发现在flush()方法中已经对异常做了处理,所以调用时不会抛出异常,我们要检测异常可以调用它的checkError()函数

 public void flush() {try {synchronized (lock) {ensureOpen();out.flush();}}catch (IOException x) {trouble = true;}}

我们关闭浏览器后,服务器下一次要推送时就会抛出异常,这个异常已经在PrintWriter的flush()中被捕捉了,我们只需它的调用checkError(),有错误的话return即可停止执行。

 if(pw.checkError()){log.println("客户端断开连接");return;}

实验结果:

断开连接

可以看到浏览器关闭了以后,服务器也跳出了这个循环

如果客户端想在不关闭页面的情况下主动关闭连接,只需要设置一个按钮,点击以后调用EventSource.colse()即可关闭连接,服务端推送数据时因为连接已经关闭,就会抛出异常,跳出循环。

服务器推送数据

客户端点击按钮后

客户端断开连接

可以看到我们点击按钮调用EventSource.close()后客户端断开连接,服务端也停止推送了。


问题3:兼容性

SSE并没有在微软的IE和Edge浏览器上实现,怎么办?

问题解决:

用第三方javascript库实现,在页面引入evensource.js就可以实现

下载地址:

https://github.com/EventSource/eventsource

实验结果:

IE

Edge

可以看到引入js文件后,IE和Edge都能支持SSE了

SSE(服务器推送事件)的介绍、问题及解决相关推荐

  1. HTML5 服务器推送事件(Server-sent Events)实战开发

    对于一般的 Web 应用开发,大多数开发人员并不陌生.在 Web 应用中,浏览器和服务器之间使用的是请求 / 响应的交互模式.浏览器发出请求,服务器根据收到的请求来生成相应的响应.浏览器再对收到的响应 ...

  2. sql server无法绑定由多个部分组成的标识符_HTML5服务器推送事件(Server-sent-event)...

    在前端开发中,实现界面推送的方式,这里大概总结下三种方式 轮询(ajax),比较耗费服务器资源.COMET方式(COMET 技术并不是 HTML 5 ) websocket 双向数据推送,灵活,功能强 ...

  3. ajax轮询模拟websocket,Ajax轮询和SSE服务器推送数据与websocket模式的区别性学习

    我们试想一下我们做个实时聊天的窗口有几种方法? 在我们不刷新页面并且可以试试更新页面内容的方法 你这时候是不是想到了ajax没错确实可以 Ajax轮询 什么是轮询?顾名思义就是我轮着问你,规定一个时间 ...

  4. sse服务器推送性能,SSE 服务端向客户端推送

    传统的ajax都是由客户端主动去请求,服务端才可以返回数据 而sse是建立一个通道,并且在断线后自动重连,由服务端去推送,不需要客户端去主动请求,只需要建立通道 websocket是双向通信 客户端可 ...

  5. sse java8_Java SSE 服务器推送WEB页面接收数据

    //服务器代码 package com.xy.inuyasha.web.controller; import javax.servlet.AsyncContext; import javax.serv ...

  6. java h5服务器推送事件_关于H5+中push推送的服务端代码是怎么写的

    您好,当我发送普通通知的时候,提交后POST数据是这样的. 发送请求 post:{"action":"pushMessageToSingleAction",&q ...

  7. html5 微信墙,HTML5服务器端推送事件 解决PHP微信墙推送问题

    问题描述 以前的文章中< PHP微信墙制作,开源 >已经用PHP搭建了一个微信墙获取信息的服务器,然后我就在想推送技术应该怎么解决,上一篇已经用了.NET 的signalr做了一个微信墙, ...

  8. 服务器推送_初探 Watermill 构建 Golang 事件驱动程序,SSE 进行 HTTP 服务器推送

    使用 SSE(Server-Sent Events) 进行 HTTP 服务器推送 这个示例是一个类似 twitter 的 web 应用程序,使用 Server-Sent Events 来支持实时刷新. ...

  9. Web服务器推送信息SSE/WebSocket

    介绍 没有简单,通用的方法来以可接受的性能在Web应用程序中实现服务器到客户端的异步通信. HTTP是客户端-服务器计算模型中的请求-响应协议.为了开始交换,客户端向服务器提交请求.为了完成交换,服务 ...

最新文章

  1. sklearn网格搜索
  2. 日志系统的设计与实现_it运维管理系统|综合运维的设计与实现
  3. [原创]K8域控植入脚本生成器(内网渗透/RPC不可用解决方案)
  4. mysql关于访问权限以及root密码修改
  5. canvas之二:绘制三角形
  6. Ubuntu在vmware虚拟机无法上网的解决方法
  7. 【技巧】Chrome应用技巧
  8. 语法分析-C语言程序
  9. DB2数据库安全的12条军规
  10. 院内适配层新版框架开发文档
  11. 计算机硬件维修教材,计算机硬件组装与维护教程(21世纪高等教育计算机规划教材)...
  12. JavaScript-callapply方法
  13. jvisualvm/Jconsole监控WAS(WebSphere)中间件
  14. 学生信息管理系统课程设计 java_java课程设计(学生信息管理系统)
  15. oracle查看当前用户表空间占用情况
  16. 硬件虚拟化检测工具:securable
  17. 渗透测试中常用的在线工具和网站总结
  18. c语言的快速排序,C语言实现快速排序法(分治法)
  19. 机器视觉系统——光源及打光
  20. Word里如何打出带有上下横杠的大写字母i

热门文章

  1. 工作中要怎么与同事相处呢?
  2. 手动修改Spyder的背景颜色(手动配色)
  3. Windows服务器忘记密码后找回方法
  4. Activity跳转后自动执行了onDestroy
  5. 华栖云携阿里云首发云上电视台服务:致力于把电视台搬上云端
  6. 在win10上通过usb连接树莓派
  7. 黑客攻防与网络安全-N-0
  8. Redis入门指南之复制
  9. Python的Scrapy框架入门教程
  10. matlab画极坐标方程图像_怎么用matlab画极坐标图