服务器发送事件(server-sent events, sse)是一种让网页实时更新的技术。想象一下,您正在浏览一个网页,而这个网页需要在有新信息时自动更新,比如新闻网站的最新消息、社交媒体的通知或股票市场的价格变动。sse使得这种实时更新成为可能,并且它是通过普通的http连接实现的,这意味着它不需要任何特殊的协议或复杂的设置。
sse的主要特点
- 基于http:sse使用标准的http协议来通信,因此它很容易集成到现有的网络架构中,无需额外配置。
- 单向数据流:与websocket不同,sse只允许服务器向客户端推送数据,而不能反过来。这对于只需要从服务器接收更新的场景非常有用,例如直播评论或通知提醒。
- 自动重连:如果由于某种原因连接中断了,浏览器会自动尝试重新连接到服务器,确保用户不会错过任何更新。
- 自定义事件类型:除了基本的数据推送外,sse还允许服务器发送特定类型的事件,这样客户端就可以根据不同的事件类型做出相应的反应。
- 轻量级和简单:相比其他如websocket等技术,sse的实现更为简单,适合不需要双向通信的应用场景。对于开发者来说,这意味着更少的代码和更容易维护的系统。
添加依赖
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-web</artifactid>
</dependency>创建sse控制器
import java.io.ioexception;
import java.util.concurrent.executorservice;
import java.util.concurrent.executors;
import org.springframework.web.bind.annotation.crossorigin;
import org.springframework.web.bind.annotation.getmapping;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.restcontroller;
import org.springframework.web.servlet.mvc.method.annotation.sseemitter;
@crossorigin
@restcontroller
@requestmapping("sse")
public class ssecontroller {
private final executorservice executorservice = executors.newcachedthreadpool();
@getmapping("/handlesse")
public sseemitter handlesse() {
sseemitter emitter = new sseemitter();
executorservice.execute(() -> {
try {
for (int i = 0; i < 10; i++) {
emitter.send(sseemitter.event().name("message").data("数据库来消息了" + i));
thread.sleep(1000);
}
emitter.complete();
} catch (ioexception | interruptedexception e) {
emitter.completewitherror(e);
}
});
return emitter;
}
}客户端实现
<!doctype html>
<html>
<body>
<h1>sse demo</h1>
<div id="messages"></div>
<button id="connectbutton">连接</button>
<button id="disconnectbutton" disabled>断开连接</button>
<script>
let eventsource = null;
const messages = document.getelementbyid('messages');
const connectbutton = document.getelementbyid('connectbutton');
const disconnectbutton = document.getelementbyid('disconnectbutton');
function connect() {
if (eventsource) return; // 如果已经连接,则不重复创建
eventsource = new eventsource('http://localhost:8081/items/handlesse');
eventsource.onmessage = function(event) {
const message = document.createelement('p');
message.textcontent = event.data;
messages.appendchild(message);
};
eventsource.onerror = function(error) {
console.error('eventsource failed:', error);
disconnect(); // 在发生错误时也尝试断开连接
};
// 禁用连接按钮,启用断开连接按钮
connectbutton.disabled = true;
disconnectbutton.disabled = false;
}
function disconnect() {
if (!eventsource) return; // 如果没有连接,则不执行任何操作
eventsource.close();
eventsource = null;
// 启用连接按钮,禁用断开连接按钮
connectbutton.disabled = false;
disconnectbutton.disabled = true;
}
// 给按钮添加事件监听器
connectbutton.addeventlistener('click', connect);
disconnectbutton.addeventlistener('click', disconnect);
</script>
</body>
</html>sse(服务器发送事件)的优缺点及适用场景
优点
- 简单易用:与websocket相比,sse不需要复杂的握手过程。它的api设计直观,开发者可以更快速地上手。
- 广泛的浏览器支持:几乎所有现代浏览器都支持sse,包括手机和平板上的浏览器,这意味着它几乎可以在任何设备上工作。
- 高效能和低延迟:相较于传统的轮询方式,sse减少了不必要的请求次数,降低了服务器负担,并提高了数据更新的速度。
- 自动重连功能:当网络连接中断时,浏览器会自动尝试重新连接到服务器,这简化了开发者的代码。
缺点
- 单向通信限制:sse只允许服务器向客户端推送信息,如果需要从客户端向服务器发送数据,则必须使用其他方法或技术。
- 依赖http长连接:虽然sse优化了数据传输,但它的实现仍然基于http连接,这可能在网络条件不佳或者通过某些代理服务器时遇到问题。
适用场景
sse非常适合用于那些只需要服务器向客户端推送实时更新的应用场景,例如:
- 实时新闻更新
- 股票价格变动通知
- 社交媒体动态提醒
- 实时评论流
- 系统状态监控
sse vs. 轮询 vs. websocket
- sse与轮询的区别:传统轮询是客户端定时询问服务器是否有新数据,这种方式不仅增加了服务器的压力,也带来了较高的延迟。而sse让服务器在有新数据时主动推送给客户端,减少了不必要的请求,提升了性能和用户体验。
- sse与websocket的对比:
- 通信方向:websocket支持双向通信,意味着客户端和服务器都可以随时发送消息;而sse仅允许服务器向客户端推送信息。
- 协议基础:websocket使用了自己的协议,而sse基于标准的http/https协议,使得sse更容易部署并且更易于调试。
- 连接管理:websocket建立后保持连接开放,直到被显式关闭;而sse会在每次事件推送后自然断开,然后根据需要重新建立连接。
- 兼容性和安全性:由于sse基于http协议,因此它在网络穿越方面表现得更好,并且能够更好地利用现有的安全机制(如https)。
- 选择建议
- 轮询:适合于对实时性要求不高、只需要偶尔检查更新的场景。不过,这种方式会增加服务器的负载。
- sse:对于需要实时推送更新但不涉及双向通信的应用来说,sse是一个很好的选择,因为它实现简单,而且浏览器兼容性好。
- websocket:适用于需要频繁双向通信的应用,比如在线聊天室或多人在线游戏。
总之,选择哪种技术取决于您的具体需求和技术栈。如果您只需要服务器向客户端推送信息,并希望实现起来尽可能简单,那么sse可能是最佳的选择。
到此这篇关于spring boot整合sse实时通信的文章就介绍到这了,更多相关spring boot sse实时通信内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论