当前位置: 代码网 > it编程>编程语言>Java > Spring Boot实现SSE实时推送实战示例

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实时推送内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com