服务器推送消息SSE以及springmvc后台实现例子

本文介绍了SSE(Server-sent Events)作为一种轻量级的WebSocket替代方案的特点与应用场景,并详细对比了SSE与WebSocket的不同之处,包括它们的数据传输频率、实现成本及数据完整性保障等关键信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是SSE?
SSE ( Server-sent Events )是 WebSocket 的一种轻量代替方案,使用 HTTP 协议,严格地说,HTTP 协议是没有办法做服务器推送的,但是当服务器向客户端声明接下来要发送流信息时,客户端就会保持连接打开,SSE 使用的就是这种原理

SSE和WebSocket比较
SSE是单向的只能从服务器端向客户端推送消息,而WebSocket是双向的可以从服务器端推送消息,也可以从客户端发送消息到服务器端。
SSE相比较于WebSocket存在如下优势为项目节约了不少成本
  • 实现一个完整的服务仅需要少量的代码;
  • 可以在现有的服务中使用,不需要启动一个新的服务;
  • 可以用任何一种服务端语言中使用;
  • 基于 HTTP / HTTPS 协议,可以直接运行于现有的代理服务器和认证技术。

如何选择推送技术?
如果需要以1次/秒或者更快的频率向服务端传输数据,那应该用WebSocket。0.2次/秒到1次/秒的频率是一个灰色地带,用WebSocket和用SSE差别不大。

SSE 如何保证数据完整性
客户端在每次接收到消息时,会把消息的 id 字段作为内部属性 Last-Event-ID 储存起来。
SSE 默认支持断线重连机制,在连接断开时会 触发 EventSource 的 error 事件,同时自动重连。再次连接成功时 EventSource 会把 Last-Event-ID 属性作为请求头发送给服务器,这样服务器就可以根据这个 Last-Event-ID 作出相应的处理。
这里需要注意的是,id 字段不是必须的,服务器有可能不会在消息中带上 id 字段,这样子客户端就不会存在 Last-Event-ID 这个属性。所以为了保证数据可靠,我们需要在每条消息上带上 id 字段。

减少开销
在 SSE 的草案中提到,"text/event-stream" 的 MIME 类型传输应当在静置 15 秒后自动断开。在实际的项目中也会有这个机制,但是断开的时间没有被列入标准中。
为了减少服务器的开销,我们也可以有目的的断开和重连。
简单的办法是服务器发送一个 关闭消息并指定一个重连的时间戳,客户端在触发关闭事件时关闭当前连接并创建 一个计时器,在重连时把计时器销毁 。

服务器后台代码(注意响应头以及固定返回数据格式)
package test;
import java.util.Random;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping(value = "/test")
public class SEEController {
//设置响应格式
	@RequestMapping(value = "/push", produces = "text/event-stream;charset=UTF-8")
	public @ResponseBody String push() {
		Random r = new Random();
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
//SSE返回数据格式是固定的以data:开头,以\n\n结束
		return "data:Testing 1,2,3" + r.nextInt() + "\n\n";
	}
}
前端html代码:(需要重写message、open、error事件)
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>SSE Demo</title>
</head>
<body>
	<div id="msg_from_server">12222</div>
	<script type="text/javascript" src="../js/jquery.js"></script>
	<script type="text/javascript">
		if (!!window.EventSource) {
			var source = new EventSource('/test/test/push'); //为http://localhost:8080/testSpringMVC/push
			s = '';
			source.addEventListener('message', function(e) {
				s += e.data + "<br/>"
				$("#msg_from_server").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 {
			alert(4);
			console.log("没有sse");
		}
	</script>
</body>
</html>



评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值