59人参与 • 2025-04-25 • Java
sse(server-sent events)是一种基于http协议的单向通信机制,允许服务器向浏览器持续发送实时更新。与websocket不同,sse更简单,使用http/1.1协议即可,不需要额外的协议升级。
sse的特点:
sse无需额外的依赖,spring boot自带对sse的支持。创建一个spring boot项目即可。
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-web</artifactid>
</dependency>使用mediatype.text_event_stream_value作为返回类型即可开启sse。以下代码是一个简单的实现。
package com.example.sse.controller;
import org.springframework.http.mediatype;
import org.springframework.web.bind.annotation.getmapping;
import org.springframework.web.bind.annotation.restcontroller;
import java.time.localtime;
import java.util.concurrent.executors;
import java.util.concurrent.timeunit;
import java.util.stream.stream;
@restcontroller
public class ssecontroller {
@getmapping(value = "/sse/stream", produces = mediatype.text_event_stream_value)
public stream<string> stream() {
// 模拟数据流
return stream.generate(() -> "当前时间:" + localtime.now())
.limit(10); // 限制10条消息
}
}默认情况下,spring boot的响应会超时。可以在application.properties中调整超时时间:
server.servlet.session.timeout=30s spring.mvc.async.request-timeout=30000
sse在前端通过eventsource对象实现。以下是一个简单的前端示例:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>sse example</title>
</head>
<body>
<h1>实时消息</h1>
<div id="messages"></div>
<script>
const eventsource = new eventsource('/sse/stream');
eventsource.onmessage = function(event) {
const messagesdiv = document.getelementbyid('messages');
const newmessage = document.createelement('p');
newmessage.textcontent = event.data;
messagesdiv.appendchild(newmessage);
};
eventsource.onerror = function() {
console.error('sse连接出错,正在尝试重连...');
eventsource.close();
};
</script>
</body>
</html>使用spring scheduler推送数据,在实际场景中,可能需要定时向客户端推送数据。例如,监控系统定时更新。
package com.example.sse.service;
import org.springframework.http.mediatype;
import org.springframework.stereotype.service;
import org.springframework.web.servlet.mvc.method.annotation.sseemitter;
import java.io.ioexception;
import java.util.concurrent.copyonwritearraylist;
@service
public class ssepushservice {
private final copyonwritearraylist<sseemitter> emitters = new copyonwritearraylist<>();
public sseemitter subscribe() {
sseemitter emitter = new sseemitter(30_000l);
emitters.add(emitter);
emitter.oncompletion(() -> emitters.remove(emitter));
emitter.ontimeout(() -> emitters.remove(emitter));
return emitter;
}
public void pushmessage(string message) {
for (sseemitter emitter : emitters) {
try {
emitter.send(message, mediatype.text_plain);
} catch (ioexception e) {
emitters.remove(emitter);
}
}
}
}创建一个控制器订阅和推送消息:
package com.example.sse.controller;
import com.example.sse.service.ssepushservice;
import org.springframework.web.bind.annotation.getmapping;
import org.springframework.web.bind.annotation.restcontroller;
@restcontroller
public class ssepushcontroller {
private final ssepushservice ssepushservice;
public ssepushcontroller(ssepushservice ssepushservice) {
this.ssepushservice = ssepushservice;
}
@getmapping("/sse/subscribe")
public sseemitter subscribe() {
return ssepushservice.subscribe();
}
@getmapping("/sse/push")
public void pushmessage() {
ssepushservice.pushmessage("当前时间:" + system.currenttimemillis());
}
}注意事项:
eventsource的onerror事件重新连接。到此这篇关于spring boot 整合 sse(server-sent events)的文章就介绍到这了,更多相关spring boot 整合 sse内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论