方法一
public SseEmitter completion() {
SseEmitter emitter = new SseEmitter(300_000L);
emitter.onCompletion(() -> log.info("SSE完成"));
emitter.onTimeout(() -> {
log.info("SSE超时");
emitter.complete();
});
emitter.onError(e -> log.error("SSE错误", e));
JSONArray jsonArray = buildJsonArray();
sseTaskExecutor.submit(() -> {
try {
emitter.send(SseEmitter.event().name("start").data("start"));
for (Object o : jsonArray) {
emitter.send(SseEmitter.event().name("message").data(o));
Thread.sleep(500);
}
emitter.send(SseEmitter.event().name("end").data("end"));
emitter.complete();
} catch (Exception e) {
emitter.completeWithError(e);
}
});
return emitter;
}
private JSONArray buildJsonArray() {
JSONArray jsonArray = new JSONArray();
JSONObject j1 = new JSONObject();
j1.put("role", "user");
j1.put("content", "我的t1");
jsonArray.add(j1);
JSONObject j2 = new JSONObject();
j2.put("role", "assistant");
j2.put("content", "你好2");
jsonArray.add(j2);
JSONObject j3 = new JSONObject();
j3.put("role", "user");
j3.put("content", "我的t3");
jsonArray.add(j3);
JSONObject j4 = new JSONObject();
j4.put("role", "assistant");
j4.put("content", "你好4");
jsonArray.add(j4);
return jsonArray;
}
方法二
public void test(HttpServletResponse response) {
response.setContentType("text/event-stream");
response.setCharacterEncoding("utf-8");
try (final PrintWriter writer = response.getWriter()) {
// 要推送的内容
final String content = "你好,我的朋友,快过年了,提前祝你新年快乐!";
int len = content.length();
int endIndex = 0;
// 每隔2个字符推送一次,模拟打字机效果
while (endIndex < len) {
endIndex = Math.min(endIndex + 2, len);
final String subContent = content.substring(0, endIndex);
// 将要推送的内容封装成JSON格式,模拟实际开发中的数据格式,非必须
final JSONObject json = new JSONObject();
json.put("data", subContent);
json.put("code", HttpStatus.OK.value());
// 最后一次推送时,type为finish,表示推送结束,其它情况为add
final String type = endIndex == len
? "finish"
: "add";
json.put("type", type);
// 组装成SSE格式的数据,发送给前端,这个格式(data: content\n\n)是固定的,content是自定义的推送内容
writer.write(getSseContent(UUID.randomUUID().toString(), type, json.toJSONString()));
writer.flush();
// 稍微给点停顿,防止数据发送太快,浏览器接收不过来
TimeUnit.MILLISECONDS.sleep(100);
}
} catch (Exception e) {
Thread.currentThread().interrupt();
}
}
private String getSseContent(String id, String event, String data) {
return "id: " + id + "\n" +
"event: " + event + "\n" +
"data: " + data + "\n\n";
}