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

什么是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事件)



SSE Demo


	
12222



你可能感兴趣的:(SSE,服务器推送,springmvc,java,web开发)