Springboot集成SSE实现消息推送之单工通信

这篇具有很好参考价值的文章主要介绍了Springboot集成SSE实现消息推送之单工通信。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

通常在一些web项目中,会涉及到想客户端推送消息,常见的有Ajax轮询、webSocket,本篇文章主要使用Springboot集成SSE实现向客户端持续推送信息。

SSE简介

服务发送事件SSE(Sever-Sent Event),就是基于 HTTP 的技术,浏览器向服务器发送一个保持长连接HTTP请求,服务器单向地向客户端以流形式持续传输数据 。这样可以节约网络资源,不需要建立新连接。

优点

服务端不需要其他的类库,开发难度较低。
不用每次建立新连接,延迟较低。
数据通过简单且广泛使用的HTTP协议而不是专有协议进行同步。

对重新建立连接和事件ID功能的内置支持。

对于利用单向通信的应用程序和服务非常有用。

缺点

客户端越多连接越多,会占用服务器大量内存和连接数。

SSE只支持UTF-8编码,不支持二进制数据。

对最大打开连接数的严格限制可能使事情变得困难,每个浏览器都设置了限制。

SSE是单向的。

Springboot集成SSE简约版

客户端发送请求到服务端,服务端以流的形式不断向客户端推送数据示例,增加帅气值。

xml依赖:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

html代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Springboot集成SSE简约版</title>
    <script type="text/javascript">
        let source = new EventSource('/get');
        source.onmessage = function (event) {
            console.info(event.data);
            document.getElementById('text').innerText = event.data
        };
    </script>
</head>
<body>
<div id="text"></div>
</body>
</html>

后端代码:

   @RequestMapping(value = "/get", produces = "text/event-stream;charset=UTF-8")
    public void push(HttpServletResponse response) {
        response.setContentType("text/event-stream");
        response.setCharacterEncoding("utf-8");
        int i = 0;
        while (true) {
            try {
                Thread.sleep(1000);
                PrintWriter pw = response.getWriter();
                //注意返回数据必须以data:开头,"\n\n"结尾
                pw.write("data:xdm帅气值加" + i + "\n\n");
                pw.flush();
                //检测异常时断开连接
                if (pw.checkError()) {
                    log.error("客户端断开连接");
                    return;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            i++;
        }
    }

效果:
spring boot 提供 sse 接口,Spring系列,java,websocket,开发语言

Springboot集成SSE升级版

演示SSE的连接建立、接收数据和异常情况监听处理。

注:若浏览器不兼容在页面引入evensource.js。

<script src=/eventsource-polyfill.js></script>

客户端代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title> Springboot集成SSE升级版</title>
</head>
<script>
    let source = null;
    const clientId = new Date().getTime();
    if (!!window.EventSource) {

        source = new EventSource('/sse/create?clientId=' + clientId);
    	//建立连接
        source.onopen = function (event) {
            setMessageInnerHTML("建立连接" + event);
        }
        //接收数据
        source.onmessage = function (event) {
            setMessageInnerHTML(event.data);
        }
        //错误监听
        source.onerror = function (event) {
            if (event.readyState === EventSource.CLOSED) {
                setMessageInnerHTML("连接关闭");
            } else {
                console.log(event);
            }
        }
    } else {
        setMessageInnerHTML("浏览器不支持SSE");
    }

    window.onbeforeunload = function () {
        close();
    };

    // 关闭
    function close() {
        source.close();
        const httpRequest = new XMLHttpRequest();
        httpRequest.open('GET', '/sse/close/?clientId=' + clientId, true);
        httpRequest.send();
        console.log("close");
    }

    // 显示消息
    function setMessageInnerHTML(innerHTML) {
        document.getElementById('text').innerHTML += innerHTML + '<br/>';
    }
</script>
<body>
<button onclick="close()">关闭连接</button>
<div id="text"></div>
</body>
</html>

服务端代码:

private static Map<String, SseEmitter> cache = new ConcurrentHashMap<>();

String clientId;
int sseId;

@GetMapping("/create")
public SseEmitter create(@RequestParam(name = "clientId", required = false) String clientId) {

    // 设置超时时间,0表示不过期。默认30000毫秒
    //可以在客户端一直断网、直接关闭页面但未提醒后端的情况下,服务端在一定时间等待后自动关闭网络连接
    SseEmitter sseEmitter = new SseEmitter(0L);
    // 是否需要给客户端推送ID
    if (Strings.isBlank(clientId)) {
        clientId = UUID.randomUUID().toString();
    }

    this.clientId = clientId;
    cache.put(clientId, sseEmitter);
    log.info("sse连接,当前客户端:{}", clientId);
    return sseEmitter;
}

@Scheduled(cron = "0/3 * *  * * ? ")
public void pushMessage() {
    try {
        sseId++;
        SseEmitter sseEmitter = cache.get(clientId);
        sseEmitter.send(
                SseEmitter
                        .event()
                        .data("帅气值暴增" + sseId)
                        .id("" + sseId)
                        .reconnectTime(3000)
        );
    } catch (Exception e) {
        log.error(e.getMessage());
        sseId--;
    }
}

@GetMapping("/close")
public void close(String clientId) {
    SseEmitter sseEmitter = cache.get(clientId);
    if (sseEmitter != null) {
        sseEmitter.complete();
        cache.remove(clientId);
    }
}

方法参数说明:

 SseEmitter
          .event()
          .data("帅气值暴增" + sseId)
          .id("" + sseId)
          .reconnectTime(3000)

SseEmitter.event()
用来得到一个记录数据的容器。


.data("帅气值暴增" + sseId)
发送给客户端的数据。


.id("" + sseId)
记录发送数据的标识,服务端可以通过HttpServletRequest的请求头中拿到这个id,判断是否中间有误漏发数据。


.reconnectTime(3000)
定义在网络连接断开后,客户端向后端发起重连的时间间隔(以毫秒为单位)。

效果:
spring boot 提供 sse 接口,Spring系列,java,websocket,开发语言
参考资料:
https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-async-objects

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/mvc/method/annotation/SseEmitter.html文章来源地址https://www.toymoban.com/news/detail-796752.html

到了这里,关于Springboot集成SSE实现消息推送之单工通信的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 详解如何通过SSE实现Web站内消息推送

    Web站内消息推送主要是通过WebSocket技术实现的,但是在某些情况下,WebSocket并不是最好的选择,比如在防火墙严格的环境下,WebSocket可能会被阻拦。 为了解决这个问题,我们可以使用SSE技术(Server-Sent Events)。 SSE是一种轻量级的服务器推送技术,可以实现服务器向客户端单

    2024年02月16日
    浏览(31)
  • Spring Boot进阶(48):【实战教程】SpringBoot集成WebSocket轻松实现实时消息推送

            WebSocket是一种新型的通信协议,它可以在客户端与服务器端之间实现双向通信,具有低延迟、高效性等特点,适用于实时通信场景。在SpringBoot应用中,集成WebSocket可以方便地实现实时通信功能,如即时聊天、实时数据传输等。         本文将介绍如何在Sprin

    2024年02月09日
    浏览(38)
  • SSE实现消息实时推送,前端渐进式学习、实践,真香

    SSE(Server Sent Event),直译为服务器发送事件,顾名思义,也就是客户端可以获取到服务器发送的事件。我们常见的 http 交互方式是客户端发起请求,服务端响应,然后一次请求完毕;但是在 sse 的场景下,客户端发起请求,连接一直保持,服务端有数据就可以返回数据给客户端

    2024年02月21日
    浏览(33)
  • 如果让你实现实时消息推送你会用什么技术?轮询、websocket还是sse

    在日常的开发中,我们经常能碰见服务端需要主动推送给客户端数据的业务场景,比如_数据大屏的实时数据_,比如_消息中心的未读消息_,比如_聊天功能_等等。 本文主要介绍SSE的使用场景和如何使用SSE。 学习就完事了 我们常规实现这些需求的方案有以下三种 轮询 websock

    2024年03月19日
    浏览(37)
  • SpringBoot集成WebSocket(实时消息推送)

    🍓 简介:java系列技术分享(👉持续更新中…🔥) 🍓 初衷:一起学习、一起进步、坚持不懈 🍓 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正🙏 🍓 希望这篇文章对你有所帮助,欢迎点赞 👍 收藏 ⭐留言 📝 🍓 更多文章请点击 调试工具 :http://coolaf.com/tool/chatt

    2024年04月29日
    浏览(31)
  • 实时通信的服务器推送机制 EventSource(SSE) 简介,附 go 实现示例

    不知道大家有没有见过 Content-Type:text/event-stream 的请求头,这是 HTML5 中的 EventSource 是一项强大的 API ,通过服务器推送实现实时通信。 与 WebSocket 相比, EventSource 提供了一种简单而可靠的单向通信机制(服务器-客户端),实现简单,适用于许多实时应用场景。 本文将介绍

    2024年02月10日
    浏览(71)
  • Java:SpringBoot整合SSE(Server-Sent Events)实现后端主动向前端推送数据

    SpringBoot整合SSE(Server-Sent Events)可以实现后端主动向前端推送数据 依赖 后端接收sse连接 前端浏览器代码 项目目录 完整依赖 pom.xml 前端代码 index.html 定义一个返回数据 Message.java 定义sse接口 SseService.java 实现sse接口 SseServiceImpl.java 定时任务 SendMessageTask.java 前端路由 IndexCont

    2024年02月10日
    浏览(32)
  • Spring Boot集成WebSocket实现消息推送

    项目中经常会用到消息推送功能,关于推送技术的实现,我们通常会联想到轮询、comet长连接技术,虽然这些技术能够实现,但是需要反复连接,对于服务资源消耗过大,随着技术的发展,HtML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

    2023年04月08日
    浏览(34)
  • 前端实现消息推送、即时通信、http简介

    服务端主动向客户端推送消息,使客户端能够即时接收到信息。 场景 页面接收到点赞,消息提醒 聊天功能 弹幕功能 实时更新数据功能 短轮询 浏览器(客户端)每隔一段时间向服务器发送http请求,服务器端在收到请求后,不论是否有数据更新,都直接进行响应。 本质:客

    2024年02月09日
    浏览(27)
  • SpringBoot SSE服务端主动推送事件详解

    SSE(Server Sent Event),直译为服务器发送事件,也就是服务器主动发送事件,客户端可以获取到服务器发送的事件。 我们常见的 http 交互方式是客户端发起请求,服务端响应,然后一次请求完毕。但是在SSE的使用场景下,客户端发起请求,然后建立SEE连接一直保持,服务端就可

    2024年02月07日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包