SSE

JavaScript 接收方

var evtSource = new EventSource("SSEServlet"); // 跨域加上  { withCredentials: true } 

// 接收消息( 消息如果已经被EventListener处理后不会到这里)
evtSource.onmessage = function(e) {
console.log("message: ", e);
}

// 接受指定消息
evtSource.addEventListener("ping", function(e) {
console.log("ping at: ", e);
}, false);

java发送方

  • servlet中需要设置的头
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
Character-Encoding: utf-8
  • servlet
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/event-stream");
response.setCharacterEncoding("utf-8");

for (int i = 0; i < 5; i++) {
// 指定事件标识
response.getWriter().write("event:me\n");
// 格式: data: + 数据 + 2个回车
response.getWriter().write("data:" + i + "\n\n");
response.getWriter().flush();
}
}
  • 返回 Flux<ServerSentEvent<T>>
@RestController
@RequestMapping("/sse")
public class SseController {

@GetMapping("/randomNumbers")
public Flux<ServerSentEvent<Integer>> randomNumbers() {
return Flux.interval(Duration.ofSeconds(1))
.map(seq -> Tuples.of(seq, ThreadLocalRandom.current().nextInt()))
.map(data -> ServerSentEvent.<Integer>builder()
.event("random")
.id(Long.toString(data.getT1()))
.data(data.getT2())
.build());
}
}
  • 或者指定produces为 MediaType.TEXT_EVENT_STREAM_VALUE
@GetMapping(value = "/flux", produces = MediaType.TEXT_EVENT_STREAM_VALUE)