SpringBoot 系列教程(六十九):SpringBoot2.x整合SSE服务端实时单向推送消息

一、需求背景

 最近需要做一个微信公众号H5端,微信打卡签到页面,在用户每天进入打卡页面时,其中其他用户打卡签到的数据需要以姓名头像的弹幕的形式在H5页面飘浮,当这个用户自己打卡签到完了之后,他的打卡数据需要以弹幕的形式展示,这是一个需要服务端实时推送消息给前端,后端一经查询到新数据,立刻通过接口返回给前端;这时候想到了WebSokcet,但是WebSocket过于笨重、复杂,我只需要这么一个效果,去继承WebSokcet有点没必要,而且WebSokcet是双向推送的一种通讯技术,想要选择一种更合适的技术,这时候就想到了Spring SSE服务端主动推送技术;

二、关于Spring SSE

服务端主动推送: SSE (Server Send Event),简称SSE,sse是保持长连接常驻, 官方文档:https://spring.io/blog/2017/03/08/spring-tips-server-sent-events-sse

三、什么是SSE消息单向推送

SSE(Server-Sent Event,服务端推送事件)是一种允许服务端向客户端推送新数据的HTML5技术。与由客户端每隔几秒从服务端轮询拉取新数据相比,这是一种更优的解决方案。。相对于与之类似的 COMET 和 WebSocket 技术来说,服务器推送事件的使用更简单,对服务器端的改动也比较小。对于某些类型的应用来说,服务器单向推送事件是最佳的选择。而与WebSocket对比的话,WebSocket是一种更为复杂的服务端实现技术,但它是真正的双向传输技术,既能从服务端向客户端推送数据,也能从客户端向服务端推送数据。

SSE的第二个优势是服务端的简洁。相对而言,WebSocket则很复杂,不借助辅助类库基本搞不定(我试过,令人痛苦)。SSE解释摘自文章:SSE:未来的解决方案2

四、搭建SpringBoot环境

1. 创建SpringBoot项目,引入Maven依赖

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.thinkingcao</groupId>
    <artifactId>springboot-sse</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-sse</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

2. 编写application.yml配置文件

#端口配置
server:
  port: 8081

spring:
  #HTML配置
  thymeleaf:
    # 模板存放路径
    prefix: classpath:/templates/
    # 模板后缀
    suffix: .html
    # 是否启用
    enabled: true
    # 模板编码
    encoding: UTF-8
    # 启用缓存,建议生产开启
    cache: false

3. 创建SSE推送SseMsgController

SSE接口规范:

(1)、需要把response的类型 改为 text/event-stream,才是sse的类型
(2)、html5新标准,用来从服务端实时推送数据到浏览器端,直接建立在当前http连接上,本质上是保持一个http长连接,轻量协议。

(3)、在返回数据时,必须用data:和\n\n分别开头和结尾,就是“信息”加上前缀“data: ”,然后以“\n\n”结尾;如:String.format("data:%s\n\n",data),不然触发不了message事件。

(4)、由于返回类型使用了text/event-stream,所以在服务端响应数据必须使用String或其他文本类型

 返回格式的说明以下图:

SseMsgController.java

package com.thinkingcao.springbootsse.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.text.SimpleDateFormat;
import java.util.Random;

/**
 * @url:  http://127.0.0.1:8081/sse
 * @desc: 服务端主动推送:SSE (Server Send Event),单向推送
 * @author: cao_wencao
 * @date: 2019-12-02 16:18
 */
@RequestMapping
@Controller
public class SseMsgController {

    @RequestMapping("/sse")
    public String see() {
        return "sse";
    }

    //这里使用输出的媒体类型为text/event-stream,这是服务端的SSE的支持
    @RequestMapping(value = "/push", produces = "text/event-stream")
    @ResponseBody
    public String push() {
        SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateStr = dateformat.format(System.currentTimeMillis());
        Random r = new Random();
        try {
            //演示每5秒向浏览器推送随机消息
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "data:Testing 服务端单向推送:=>" + dateStr+ "\n\n";
    }

}

  Controller截图如下:

4. 在templates目录下新建sse.html

 SSE推送技术里最核心的对象是EventSource(),EventSource()对象里的参数就是服务器推送的请求路径了,要注意的是,EventSource目前并不为IE所支持,请在谷歌或火狐等浏览器下尝试。

客户端对数据的通信是通过js的EventSource来进行的,EventSource提供了三个事件:

SSE技术详解:一种全新的HTML5服务器推送事件技术_QQ20160526-0.png

我们可以像实例代码一样通过注册监听器实现推送接送功能,也可以使用以下这种形式:source.onXXXX=function(e){...}实现。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>SSE服务端消息单向推送</title>
</head>
<body>
<div id="sseMsg"></div>
<script src="https://code.jquery.com/jquery-3.0.0.min.js"></script>
<script type="text/javascript">
    if (!!window.EventSource) { //EventSource对象只有新式的浏览器才有(Chrome、Firefox)等,EventSource是SSE的客户端
        var source = new EventSource('push');
        s = '';
        //添加SSE客户端监听,在此获得服务器端推送的消息
        source.addEventListener('message', function (e) {
            s += e.data + "<br/>";
            $("#sseMsg").html(s);

        });
        source.addEventListener('open', function (e) {
            console.log("连接打开.........");
        }, false);
        source.addEventListener('error', function (e) {
            if (e.readyState == EventSource.CLOSED) {
                console.log("连接关闭.........");
            } else {
                console.log(e.readyState);
            }
        }, false);
    } else {
        console.log("你的浏览器不支持SSE");
    }
</script>
</body>
</html>

5.启动类

package com.thinkingcao.springbootsse;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringbootSseApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootSseApplication.class, args);
    }

}

五、SSE服务端实时单向推送消息测试

打开谷歌浏览器,输入请求地址: http://127.0.0.1:8081/sse    ,按一下F12,打开谷歌浏览器调试模式,如下图所示:

 

以上SpringBoot2.x整合SpringSSE服务端实时单向推送消息只是作为本人入门接触的一个案例,更深层次的原理和复杂功能还需另行查询资料;

六、源码

源码: https://github.com/Thinkingcao/SpringBootLearning/tree/master/springboot-sse

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

发布了276 篇原创文章 · 获赞 169 · 访问量 66万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览