SSE技术

147 阅读2分钟

一、SSE技术(总结来自编程导航www.codefather.cn/

1、前后端实时通讯方案(主流)

1)轮询(前端主动去要)

前端间隔一定时间就调用后端提供的结果接口,比如200ms一次,后端处理一些结果就累加放在缓存中。

2)SSE(后端推送给前端)

前端发送请求并和后端建立连接后,后端可以实时推送数据给前端,无需前端自主轮询。

3)WebSocket

全双工协议,前端能实时推送数据给后端(或者从后端缓存拿数据),后端也可以实时推送数据给前端。

2、基本概念

​ 服务器发送事件(Server-Sent Events)是一种用于从服务器的 单向实时数据传输技术,基于HTTP协议实现。

3、特点

1)单向通信

SSE只支持服务器向客户端的单向通信,客户端不能向服务器发送数据。

2)文本格式

SSE使用纯文本格式传输数据,使用HTTP响应的 text/event-stream MIME类型。

3)保持连接

SSE通过保持一个持久的HTTP连接,实现服务器向客户端推送更新,而不需要客户端频繁轮询。

4)自动重连

如果连接中断,浏览器会自动尝试重新连接,确保数据流的连续性。

4、SSE数据格式

SSE数据流的格式非常简单,每一个事件使用data字段,事件以两个换行符结束。还可以使用id字段来标识事件,并且retry字段可以设置重新连接的时间间隔。

例如:

data: First message\n
\n
data: Second message\n
\n
data: Third message\n
id: 3\n
\n
retry: 10000\n
data: Fourth message\n
\n

5、实现SSE

1)服务器端

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/sse")
public class SseServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/event-stream");
        response.setCharacterEncoding("UTF-8");
        PrintWriter writer = response.getWriter();
        for (int i = 0; i < 10; i++) {
            writer.write("data: Message " + i + "\n\n");
            writer.flush();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        writer.close();
    }
}

Spring 项目(一定要使用Get请求)

@GetMapping("/sse")
public SseEmitter testSSE() {
    // 建立 SSE 连接对象,0 表示不超时
    SseEmitter emitter = new SseEmitter(0L);   
    ... 业务逻辑处理
    return emitter;
}

2)Web前端

// 创建 SSE 请求
const eventSource = new EventSource(
  "http://localhost:8080/sse"
);
// 接收消息
eventSource.onmessage = function (event) {
  console.log(event.data);
};
// 生成结束,关闭连接
eventSource.onerror = function (event) {
  if (event.eventPhase === EventSource.CLOSED) {
    eventSource.close();
  }
};

6、应用场景

1)AI对话

2)实时更新

股票价格、体育比赛比分、新闻更新等需要实时推送的应用

3)日志监控

实时监控服务器日志或应用状态

4)通知系统

向客户段推送系统通知或者消息