java对接华为推送服务_java服务端推送消息有那么难吗?

本文介绍了如何使用SSE(Server-sent Events)技术在Java服务端实现消息推送,对比了SSE与WebSocket的区别,并展示了Spring Mvc中SSE的使用方法,包括SseEmitter对象的创建和事件发送。最后提到了SSE在特定业务场景下的优势,并提供了相关代码仓库链接。
摘要由CSDN通过智能技术生成

e5436ef85847b52d7cf00b5f77e87be8.gif

ed13a06abd5fe8d4fab8b10f68ebe038.png

场景

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

526d284198fba0c5b0cbb624a5cd8b3e.png

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

2df7fcfffa4938b660bb4edcc5e3ee54.png

1

SSE推送技术

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

a27ff8c3dccfedf17cf3e8e2597c6ee9.png

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

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

 key定义有以下几种:

  •  data,表示该行包含的是数据。以 data 开头的行可以出现多次。所有这些行都是该事件的数据。

  • event,表示该行用来声明事件的类型。浏览器在收到数据时,会产生对应类型的事件。默认提供三个标准事件(当然你可以自定义):

220660bfb6a8d918dba3df2da67236ee.png

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

  • retry,表示该行用来声明浏览器在连接断开之后进行再次连接之前的等待时间。

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

2

SSE VS Websocket

  • SSE 只能Server到Client单项,而Websocket是双向通信。

  • SSE 比 Websocket 轻量。当然功能要简单的多。开发便利,不牵涉协议升级问题。

  • SSE 天然支持断线重连

3

Spring Mvc中的SSE

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

836f30118da659f64af358deacb84bd3.png

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

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

4

浏览器端的EventSource

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

  • 声明客户端连接, 初始化EventSource对象。

  • 编写监听器来监听事件。

1f91ee3203c19147d1764b7f924406d6.png

总结

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

https://gitee.com/felord/sse-push

c1fe29f57a6f1c111c748d4888b0e2a8.gif

● 全网首发Spring Cloud Gateway 添加统一前缀功能

● 最详细的自定义Spring Boot Starter开发教程

● Java入门必看的Java 8 Stream API 使用指南

ec847f40f2295fb95323083e565da320.png

扫码关注

更多技术干货

请从公众号菜单查阅

7a8e1c9d9440c59ab7620279ef8f7a4a.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值