微信搜索“品茗IT”关注我们吧!

一、概述

提到服务端数据推送,你可以一下子就想到了Websocket,WebSocket是一种全新的协议,随着HTML5草案的不断完善,越来越多的现代浏览器开始全面支持WebSocket技术了,它将TCP的Socket(套接字)应用在了webpage上,从而使通信双方建立起一个保持在活动状态连接通道。

但你可能不知道,HTML5中有一个轻量的替代Websocket的方案:SSE(Server-Sent Events)。

WebSocket 和 SSE 都是传统请求-响应 Web 架构的替代方案,但它们不是完全冲突的技术。

  • WebSocket 架构在客户端与服务器之间打开一个套接字,用于实现全双工(双向)通信。
    无需发送 GET 消息并等待服务器响应,客户端只需监听该套接字,接收服务器更新,并使用收到的数据来发起或支持各种交互。
    客户端也可以使用套接字与服务器通信,例如在成功收到更新时发送 ACK 消息。

  • SSE 是一种更简单的标准,是作为 HTML5 的扩展而开发的。
    尽管 SSE 支持从服务器向客户端发送异步消息,但客户端无法向服务器发送消息。
    对于客户端只需接收从服务器传入的更新的应用程序,SSE 的半双工通信模型最适合。
    与 WebSocket 相比,SSE 的一个优势是它是基于 HTTP 而运行的,不需要其他组件。

几乎所有现代浏览器都支持 WebSocket 协议,包括移动浏览器。然而Microsoft IE 和 Edge不支持SSE
但这并不妨碍我们使用SSE,毕竟用IE的人还有几个呢?如果是内部使用,为什么不使用更简单的SSE呢?

本篇不讲websocket,有兴趣的可以阅读WebSocket做简单的聊天室了解更多关于websocket的使用。

这里讲述如何使用SSE建立服务端的推送。

二、服务端

这里我们使用聊天来模拟SSE的数据推送。我这里写了几个自定义的对象

  • Chater对象存储聊天人的信息。

  • WebSSEUser是一个存储用户名userName和Chater对象的map。

2.1 配置

在Springboot项目中使用SSE,是不需要额外引入依赖的,只需要把spring-boot-starter-web引入即可。也不需要额外的配置。

<dependency>    <groupId>org.springframework.bootgroupId>    <artifactId>spring-boot-starter-webartifactId>dependency>

2.2 服务端text/event-stream长连接

要使用SSE,首先需要定义一个维持SSE长连接的接口地址,就像websocket中定义websocket的端口地址一样,但是SSE这里和普通的http没有多大区别,只是响应头是text/event-stream.

示例:

@GetMapping(value = "/subscribe", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public SseEmitter to(HttpServletRequest request) {    String userName = (String) request.getSession().getAttribute("userName");    // 超时时间设置为3分钟    SseEmitter sseEmitter = new SseEmitter(180000L);    Chater chater = WebSSEUser.getChater(userName);    sseEmitter.onTimeout(() -> chater.setSseEmitter(null));    sseEmitter.onCompletion(() -> System.out.println("完成!!!"));    chater.setSseEmitter(sseEmitter);    return sseEmitter;}

这里是Springboot应用中使用SSE,我定义了/subscribe接口:

  • produces指定了响应类型text/event-stream

  • userName从session中获取,并获取到聊天对象Chater。

  • 这里调用时创建SseEmitter对象,设置超时时间3分钟,onTimeout超时后清除SseEmitter对象,因为SSE可以超时重连,超时会再次调用这个接口,就会重新生成SseEmitter对象。

  • onCompletion完成后逻辑自定义,但是不要清除SseEmitter对象,否则会一直重连。

SSE调用/subscribe接口接口以后,会一直使用一个请求,类似websocket。

2.3 服务端发送消息

上面的代码只是保持了长连接,而且是单向的,只能是服务端给客户端发消息。

单向的意思就是,客户端不能通过SSE去发送消息,服务端可以通过SSE给客户端发送消息。

但是我们还是可以使用SSE来完成聊天功能的,因为客户端可以通过普通http请求去发送消息,到服务端以后再发送给其他客户端。

示例:

@RequestMapping(value = "/send")public ResultModel send(@RequestBody MessageDTO messageDTO, HttpServletRequest request) {    logger.info("收到发往用户[{}]的文本请求;", messageDTO.getTargetUserName());    Object userName = request.getSession().getAttribute("userName");    if (userName == null)        return ResultModel.error("无用户");    messageDTO.setFromUserName((String) userName);    messageDTO.setMessageType(Type.TYPE_TEXT.getMessageType());    Chater chater = WebSSEUser.getChater(messageDTO.getTargetUserName());    try {        chater.getSseEmitter().send(messageDTO);    } catch (IOException e) {        e.printStackTrace();    }    return ResultModel.ok();}

这里,通过目标的userName获取到Chater对象,然后Chater对象中保存有SseEmitter对象,SseEmitter对象可以直接发送消息到客户端。

三、客户端

前面讲述了服务端维持SSE的方法。下面讲述下客户端如何操作。

3.1 SSE连接

调用服务端的/subscribe接口,维持长连接,请阅服务端消息。

var url = "/subscribe";var es = new EventSource(url);es.addEventListener("message", function(e){    decode(e);},false);

不需要额外引入js,addEventListener中可以调用其他方法对消息解析并操作。

这里的decode(e);是对应服务端的chater.getSseEmitter().send(messageDTO);

3.2 普通http请求发送消息

普通的ajax请求即可,无需额外处理,调用服务端的/send接口即可。

四、截图

如图:

在这里插入图片描述
  1. 客户端连接服务端的/subscribe接口,这个连接会一直持续下去,图上已经持续了十几秒。

  2. 客户端连接服务端的/send接口,发送消息给服务端,服务端转发给其他客户端。

这里就先说这么多了,可以点击左下方的【阅读原文】查看完整的关于sse的介绍!

欢迎在评论区留下你的观点,一起讨论提高。

如果今天的文章让你有新的启发,或者在学习能力的提升上有新的认识,欢迎转发分享给更多人。

欢迎各位读者加入品茗IT技术群聊,群号:801159061

websocket session超时_SSE(ServerSent Events):替代websocket完成服务器推送相关推荐

  1. HTTP Websocket 服务器推送消息

    文章目录 HTTP HTTP请求过程 1. 无状态 2. 基于TCP协议 心跳包 3. 长.短连接 4. 单向请求 传统服务器推送技术 短轮询 polling 同源限制 跨域资源共享 长轮询 long ...

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

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

  3. JS 服务器推送技术 WebSocket 入门指北

    作者: 前端下午茶  公号 / SHERlocked93 最近在工作中遇到了需要服务器推送消息的场景,这里总结一下收集整理WebSocket相关资料的收获. 1. 概述 1.1 服务器推送 WebSo ...

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

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

  5. Spring之WebSocket网页聊天以及服务器推送

    Spring之WebSocket网页聊天以及服务器推送 转自:http://www.xdemo.org/spring-websocket-comet/ /Springframework /Spring ...

  6. 基于Tomcat7、Java、WebSocket的服务器推送聊天室

    2019独角兽企业重金招聘Python工程师标准>>> 基于Tomcat7.Java.WebSocket的服务器推送聊天室 转载于:https://my.oschina.net/u/ ...

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

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

  8. 服务器推送技术之短轮询、长轮询、SSE和Websocket

    服务器推送技术 服务器推送技术干嘛用?就是让用户在使用网络应用的时候,不需要一遍又一遍的去手动刷新就可以及时获得更新的信息.大家平时在上各种视频网站时,对视频节目进行欢乐的吐槽和评论,会看到各种弹幕, ...

  9. 【JavaWeb】小白也能看懂的服务器推送技术(WebSocket和SSE)

    一.什么是消息推送 推送的场景比较多,比如有人关注我的公众号,这时我就会收到一条推送消息,以此来吸引我点击打开应用. 消息推送(push)通常是指网站的运营工作等人员,通过某种工具对用户当前网页或移动 ...

最新文章

  1. Github注册过程以及对管理软件的了解
  2. 中国基础软件历史性突破!Gartner最新报告:阿里云进入全球数据库领导者象限
  3. 【NOIP2012模拟10.20】友好数对
  4. XML——文档类型定义(DTD-Document Type Definition)
  5. css less 不要作用到子对象_CSS-预处理语言Sass、Less简述
  6. [css] 举例说明伪类:focus-within的用法
  7. 语义分割之OCR的评判标准
  8. WCF热带鱼书学习手记 - ABC
  9. android手机冻屏问题,android 模拟冻屏 代码实现
  10. Understanding Growth
  11. MySQL数据库基础教程(视频)
  12. 离散数学及其应用【华章版】习题答案第一章01
  13. 世外桃源六python_中土世界的世外桃源——新西兰霍比特人小镇全攻略
  14. 通达信交易服务器修改,GitHub - sjj6love/TdxTradeServer: TongDaXin Tarde Server 通达信交易服务器...
  15. codelite开发php,wxWidgets(2):一个好用C/C++ php 开源IDE -- CodeLite IDE
  16. JSON必备工具之Json Viewer
  17. 13:求圆的周长和面积
  18. 【Java】- Incompatible types. Found: java. lang. String', required:' byte, char, short or int'
  19. Tushare Day4——导入IPO新股列表new_share并分析基金和盈利
  20. demoのpython学习笔记【1】

热门文章

  1. mysql 联合索引长度_MySQL 中索引的长度的限制
  2. linux输入ls命令报错,Linux命令基础2-ls命令
  3. python输入输出流详解_Python 初体验之 输入输出流
  4. linux 内核 call,在Linux Kernel內新增一个System Call(转)
  5. 【ES6】 let与const详解
  6. CLion报错解决:allocating an object of abstract class type--unimplemented pure virtual method
  7. matlab门槛回归,重磅!这可能是最全的门槛回归汇总了
  8. mysql 主从单表_MySQL主从复制单表或者多表
  9. C++_泛型编程与标准库(一)
  10. 在文件log 加入commit id_从物理文件理解InnoDB Redo Log