server向浏览器发送信息-SseEmitter使用
什么是SseEmitter
SseEmitter 是 Spring 框架中的一个类,用于支持服务器发送事件(Server-Sent Events, SSE)。SSE 是一种允许服务器主动向客户端推送实时更新的技术,通常用于需要实时数据更新的应用场景,如股票行情、社交媒体通知等。
在 Spring 中,SseEmitter 提供了一种简单的方式来实现 SSE。通过 SseEmitter,服务器可以在一个长连接中不断地向客户端发送事件,而客户端则可以通过 JavaScript 的 EventSource 对象来接收这些事件
和websocket的区别
SseEmitter(Server-Sent Events)和 WebSocket 是两种不同的技术,用于在客户端和服务器之间进行实时通信。它们有各自的特点和适用场景。
-
SseEmitter(Server-Sent Events,SSE):
- 单向通信:SSE 是一种单向通信协议,服务器可以向客户端发送更新,但客户端不能向服务器发送数据。
- 基于HTTP:SSE 使用 HTTP 协议,客户端通过 HTTP 请求订阅服务器的事件流,服务器通过持续的 HTTP 响应发送事件。
- 简单实现:SSE 的实现相对简单,特别适合于需要从服务器向客户端推送实时更新的场景,如股票行情、新闻推送等。
- 浏览器支持:大多数现代浏览器都支持 SSE,但在某些旧版本的浏览器中可能不支持。
-
WebSocket:
- 双向通信:WebSocket 是一种全双工通信协议,允许客户端和服务器之间进行双向数据传输。
- 独立协议:WebSocket 是一个独立的协议,虽然最初的握手是通过 HTTP 完成的,但一旦连接建立,通信就不再依赖于 HTTP。
- 高效传输:WebSocket 连接一旦建立,数据传输效率高,适合需要频繁、低延迟通信的场景,如在线游戏、实时聊天应用等。
- 复杂实现:WebSocket 的实现相对复杂,需要处理连接的建立、维护和关闭等细节。
总结:
- 如果你的应用场景只需要服务器向客户端推送数据,并且实现简单是一个重要考虑因素,那么可以选择 SseEmitter(SSE)。
- 如果你的应用场景需要双向实时通信,并且对传输效率和低延迟有较高要求,那么 WebSocket 是更好的选择。
代码示例
import org.springframework.web.bind.annotation.*;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/chat")
public class ChatController {
private List<SseEmitter> emitters = new ArrayList<>();
//发送
@PostMapping("/send")
public void sendMessage(@RequestBody ChatMessage message) {
for (SseEmitter emitter : emitters) {
try {
emitter.send(message, MediaType.APPLICATION_JSON);
} catch (IOException e) {
emitter.completeWithError(e);
}
}
}
//接收
@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter streamMessages() {
SseEmitter emitter = new SseEmitter(60000L); //超时时间
emitters.add(emitter);
emitter.onCompletion(() -> emitters.remove(emitter));
emitter.onTimeout(() -> emitters.remove(emitter));
return emitter;
}
}
//信息体
@Data
public class ChatMessage {
private String sender;
private String content;
private String timestamp;
// Getters and Setters
}
/chat/stream 接收到的消息