您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > JAVA

Java服务端推送消息有那么难吗?

时间:2019-08-28 13:58:54  来源:  作者:

原文地址:https://dwz.cn/FFB05DFg

作者:码农小胖哥

场景:

今天项目经理交给我一个开发任务。如果有人在前台下了订单就给后台仓库管理一个发货通知。也就是服务端触发一个事件,推送消息到客户端。

如果我用websocket来做还要搞个websocket服务器,而且还 有不少配置。websocket是全双工通信,单向通信简直是杀鸡用牛刀。用轮询吧,浪费服务器资源不说,还不一定实时,订单处理慢了岂不是怠慢了客户。有没有别的选择呢?当然有!

Java服务端推送消息有那么难吗?

 

1.SSE推送技术

SSE全称Server-sent Events,是html 5 规范的一个组成部分,具体去MDN网站查看相关文档。该规范十分简单,主要由两个部分组成:第一个部分是服务器端与浏览器端之间的通讯协议,第二部分是在浏览器端可供 JAVAScript 使用的 EventSource 对象。通讯协议是基于纯文本的简单协议。服务器响应的内容类型是“text/event-stream”。响应文本的内容可以看成是一个事件流,由不同的事件所组成。每个事件由类型和数据两部分组成,同时每个事件可以有一个可选的标识符。不同事件的内容之间通过仅包含回车符和换行符的空行(“rn”)来分隔。每个事件的数据可能由多行组成。

Java服务端推送消息有那么难吗?

 

如上图所示,每个事件之间通过空行来分隔。每一行都是由键值对组成。如果键为空则表示该行为注释,会在处理时被忽略。例如第10行。

第1行表示一个只包含数据的事件。会按照默认事件走(message事件)。第3-4行代表一个附带eventID的事件。第6-8行代表一个自定义事件。第10-14行代表一个多行数据事件,多行数据由换行符链接

key定义有以下几种:

  • data,表示该行包含的是数据。以 data 开头的行可以出现多次。所有这些行都是该事件的数据。
  • event,表示该行用来声明事件的类型。浏览器在收到数据时,会产生对应类型的事件。默认提供三个标准事件(当然你可以自定义):
Java服务端推送消息有那么难吗?

 

  • id,表示该行用来声明事件的标识符。服务器端返回的数据中包含了事件的标识符,浏览器会记录最近一次接收到的事件的标识符。如果与服务器端的连接中断,当浏览器端再次进行连接时,会通过 HTTP 头“Last-Event-ID”来声明最后一次接收到的事件的标识符。服务器端可以通过浏览器端发送的事件标识符来确定从哪个事件开始来继续连接。
  • retry,表示该行用来声明浏览器在连接断开之后进行再次连接之前的等待时间。

SSE只适用于高级浏览器,但是注意IE不直接支持。IE上的XMLHttpRequest对象不支持获取部分的响应内容,所以不支持。每次总有IE,怪不得快被淘汰了。

2.SSE VS Websocket

  • SSE 只能Server到Client单项,而Websocket是双向通信。
  • SSE 比 Websocket 轻量。当然功能要简单的多。开发便利,不牵涉协议升级问题。
  • SSE 天然支持断线重连

3.Spring Mvc中的SSE

Spring Mvc对SSE进行了支持。如果你要声明一个SSE连接。只需要在你的控制器声明一个如下接口:

Java服务端推送消息有那么难吗?

 

必须必须返回SseEmitter对象,SseEmitter对象是Session级别的,如果你要点对点针对每个session要独立存储。如果你是广播可以共用一个SseEmitter对象。按照SSE规范也必须声明produces为"text/event-stream"。当你调用该接口的时候将建立起SSE连接。

你可以在另一个线程中调用SseEmitter的send方法向客户端发送事件。你也可以在发送事件后调用complete方法来关闭SSE连接。

4.浏览器端的EventSource

由于SSE 是HTML5规范。所以对于App端必须有HTML才能支持。并且IE如果要支持需要使用一些兼容开发包,比如polyfill库。客户端因为只接受事件所以开发比较简单:

  • 声明客户端连接, 初始化EventSource对象。
  • 编写监听器来监听事件。
Java服务端推送消息有那么难吗?

 

今天介绍了SSE 服务端推送。和长轮训、comet、websocket相比而言比较轻量级。在一些需要服务器实时推送规模不大的业务场景实现更简单点。相信看了本文后你会很快入门。在实际开发中要根据业务对这几种推送进行技术选型。没有最好的只有最适合的。SSE对大多数开发者来说不够熟悉。



Tags:Java 推送消息   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
如果我用websocket来做还要搞个websocket服务器,而且还 有不少配置。websocket是全双工通信,单向通信简直是杀鸡用牛刀。用轮询吧,浪费服务器资源不说,还不一定实时,订单处理慢了岂不是怠慢了客户。有没有别的选择呢?当然有...【详细内容】
2019-08-28  Tags: Java 推送消息  点击:(198)  评论:(0)  加入收藏
▌简易百科推荐
面向对象的特征之一封装 面向对象的特征之二继承 方法重写(override/overWrite) 方法的重载(overload)和重写(override)的区别: 面向对象特征之三:多态 Instanceof关键字...【详细内容】
2021-12-28  顶顶架构师    Tags:面向对象   点击:(2)  评论:(0)  加入收藏
一、Redis使用过程中一些小的注意点1、不要把Redis当成数据库来使用二、Arrays.asList常见失误需求:把数组转成list集合去处理。方法:Arrays.asList 或者 Java8的stream流式处...【详细内容】
2021-12-27  CF07    Tags:Java   点击:(3)  评论:(0)  加入收藏
文章目录 如何理解面向对象编程? JDK 和 JRE 有什么区别? 如何理解Java中封装,继承、多态特性? 如何理解Java中的字节码对象? 你是如何理解Java中的泛型的? 说说泛型应用...【详细内容】
2021-12-24  Java架构师之路    Tags:JAVA   点击:(5)  评论:(0)  加入收藏
大家好!我是老码农,一个喜欢技术、爱分享的同学,从今天开始和大家持续分享JVM调优方面的经验。JVM调优是个大话题,涉及的知识点很庞大 Java内存模型 垃圾回收机制 各种工具使用 ...【详细内容】
2021-12-23  小码匠和老码农    Tags:JVM调优   点击:(12)  评论:(0)  加入收藏
前言JDBC访问Postgresql的jsonb类型字段当然可以使用Postgresql jdbc驱动中提供的PGobject,但是这样在需要兼容多种数据库的系统开发中显得不那么通用,需要特殊处理。本文介绍...【详细内容】
2021-12-23  dingle    Tags:JDBC   点击:(13)  评论:(0)  加入收藏
Java与Lua相互调用案例比较少,因此项目使用需要做详细的性能测试,本内容只做粗略测试。目前已完成初版Lua-Java调用框架开发,后期有时间准备把框架进行抽象,并开源出来,感兴趣的...【详细内容】
2021-12-23  JAVA小白    Tags:Java   点击:(11)  评论:(0)  加入收藏
Java从版本5开始,在 java.util.concurrent.locks包内给我们提供了除了synchronized关键字以外的几个新的锁功能的实现,ReentrantLock就是其中的一个。但是这并不意味着我们可...【详细内容】
2021-12-17  小西学JAVA    Tags:JAVA并发   点击:(11)  评论:(0)  加入收藏
一、概述final是Java关键字中最常见之一,表示“最终的,不可更改”之意,在Java中也正是这个意思。有final修饰的内容,就会变得与众不同,它们会变成终极存在,其内容成为固定的存在。...【详细内容】
2021-12-15  唯一浩哥    Tags:Java基础   点击:(17)  评论:(0)  加入收藏
1、问题描述关于java中的日志管理logback,去年写过关于logback介绍的文章,这次项目中又优化了下,记录下,希望能帮到需要的朋友。2、解决方案这次其实是碰到了一个问题,一般的情况...【详细内容】
2021-12-15  软件老王    Tags:logback   点击:(19)  评论:(0)  加入收藏
本篇文章我们以AtomicInteger为例子,主要讲解下CAS(Compare And Swap)功能是如何在AtomicInteger中使用的,以及提供CAS功能的Unsafe对象。我们先从一个例子开始吧。假设现在我们...【详细内容】
2021-12-14  小西学JAVA    Tags:JAVA   点击:(22)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条