欢迎来到徐庆高(Tea)的个人博客网站
磨难很爱我,一度将我连根拔起。从惊慌失措到心力交瘁,我孤身一人,但并不孤独无依。依赖那些依赖我的人,信任那些信任我的人,帮助那些给予我帮助的人。如果我愿意,可以分裂成无数面镜子,让他们看见我,就像看见自己。察言观色和模仿学习是我的领域。像每个深受创伤的人那样,最终,我学会了随遇而安。
当前位置: 日志文章 > 详细内容

Spring Boot实现SSE实时推送实战示例

2025年08月11日 Java
以下是一个完整的基于 spring boot 的 server-sent events (sse) 示例,包括服务端和客户端的实现。一、服务端实现1. 创建 spring boot 项目首先,创建一个

以下是一个完整的基于 spring boot 的 server-sent events (sse) 示例,包括服务端和客户端的实现。

一、服务端实现

1. 创建 spring boot 项目

首先,创建一个基本的 spring boot 项目,并添加 spring-boot-starter-web 依赖。在 pom.xml 中添加以下内容:

<dependencies>
    <dependency>
        <groupid>org.springframework.boot</groupid>
        <artifactid>spring-boot-starter-web</artifactid>
    </dependency>
</dependencies>

2. 创建 sse 控制器

创建一个控制器来处理 sse 连接并推送实时消息。

ssecontroller.java

package com.example.sse;
import org.springframework.http.mediatype;
import org.springframework.web.bind.annotation.getmapping;
import org.springframework.web.bind.annotation.restcontroller;
import org.springframework.web.servlet.mvc.method.annotation.sseemitter;
import java.io.ioexception;
import java.util.concurrent.executorservice;
import java.util.concurrent.executors;
import java.util.concurrent.timeunit;
@restcontroller
public class ssecontroller {
    private final executorservice executorservice = executors.newcachedthreadpool();
    @getmapping("/sse")
    public sseemitter handlesse() {
        sseemitter emitter = new sseemitter();
        executorservice.execute(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    emitter.send("message " + i, mediatype.text_plain);
                    timeunit.seconds.sleep(1);
                }
                emitter.complete();
            } catch (ioexception | interruptedexception e) {
                emitter.completewitherror(e);
            }
        });
        return emitter;
    }
}

3. 配置跨域(可选)

如果前端和后端运行在不同端口上,需要配置跨域。

corsconfig.java

package com.example.sse;
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import org.springframework.web.servlet.config.annotation.corsregistry;
import org.springframework.web.servlet.config.annotation.webmvcconfigurer;
@configuration
public class corsconfig implements webmvcconfigurer {
    @override
    public void addcorsmappings(corsregistry registry) {
        registry.addmapping("/**")
                .allowedoriginpatterns("*")
                .allowedmethods("get", "post", "put", "delete")
                .allowedheaders("*")
                .allowcredentials(true);
    }
}

二、客户端实现

在前端页面中,使用 eventsource 来订阅 sse。

index.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>sse example</title>
</head>
<body>
    <h1>server-sent events example</h1>
    <div id="events"></div>
    <script>
        const eventsource = new eventsource('/sse');
        eventsource.onmessage = function(event) {
            const newelement = document.createelement("div");
            newelement.innerhtml = "message: " + event.data;
            document.getelementbyid("events").appendchild(newelement);
        };
        eventsource.onerror = function(event) {
            eventsource.close();
            alert("eventsource failed: " + event);
        };
    </script>
</body>
</html>

三、运行和测试

  1. 启动 spring boot 应用。
  2. 在浏览器中访问 http://localhost:8080,即可看到服务端每秒推送的消息。

四、扩展功能

1. 动态推送消息

可以通过维护一个 sseemitter 的映射来动态推送消息。

ssecontroller.java(动态推送版本)

package com.example.sse;
import org.springframework.http.mediatype;
import org.springframework.web.bind.annotation.*;
import java.io.ioexception;
import java.util.map;
import java.util.concurrent.concurrenthashmap;
@restcontroller
public class ssecontroller {
    private final map<string, sseemitter> emittermap = new concurrenthashmap<>();
    @getmapping("/sse/{userid}")
    public sseemitter connect(@pathvariable string userid) {
        sseemitter emitter = new sseemitter();
        emittermap.put(userid, emitter);
        emitter.oncompletion(() -> emittermap.remove(userid));
        emitter.ontimeout(() -> emittermap.remove(userid));
        emitter.onerror(e -> emittermap.remove(userid));
        return emitter;
    }
    @getmapping("/push/{userid}")
    public void push(@pathvariable string userid, @requestparam string message) {
        sseemitter emitter = emittermap.get(userid);
        if (emitter != null) {
            try {
                emitter.send(message);
            } catch (ioexception e) {
                emitter.completewitherror(e);
                emittermap.remove(userid);
            }
        }
    }
}

2. 使用 webflux 实现 sse

如果需要更高效的响应式编程支持,可以使用 spring webflux。

ssecontroller.java(webflux 版本)

package com.example.sse;
import org.springframework.http.mediatype;
import org.springframework.http.codec.serversentevent;
import org.springframework.web.bind.annotation.getmapping;
import org.springframework.web.bind.annotation.restcontroller;
import reactor.core.publisher.flux;
import java.time.duration;
@restcontroller
public class ssecontroller {
    @getmapping("/sse/stream")
    public flux<serversentevent<string>> streamsse() {
        return flux.interval(duration.ofseconds(1))
                .map(sequence -> serversentevent.<string>builder()
                        .id(string.valueof(sequence))
                        .event("periodic-event")
                        .data("current time: " + java.time.localtime.now())
                        .build());
    }
}

通过以上步骤,你可以实现一个完整的基于 spring boot 的 sse 应用。

到此这篇关于spring boot实现sse实时推送实战示例的文章就介绍到这了,更多相关springboot sse实时推送内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!