SSE(Server-Sent Events)
时间: 2025-07-01 10:27:13 浏览: 20
### 什么是 Server-Sent Events (SSE)
Server-Sent Events (SSE) 是一种基于 HTTP 的技术,允许服务器向客户端推送实时更新的数据流。它是一种单向通信机制,适合用于需要从服务器到客户端持续传输数据的应用场景[^1]。
---
### SSE 的主要特点
- **单向通信**:SSE 只支持从服务器到客户端的单向数据流,不支持双向通信。
- **低延迟**:相比轮询或其他传统方法,SSE 提供更低的延迟和更高的效率。
- **标准协议**:SSE 基于 HTTP 协议,兼容性强,易于实现。
- **事件驱动模型**:可以通过自定义事件名称来区分不同的消息类型。
---
### SSE 的基本工作原理
当客户端请求一个支持 SSE 的资源时,服务器会保持连接并定期发送数据直到连接关闭或超时。每次发送数据时,服务器可以指定特定的消息格式和元信息,例如事件名称、重试时间等[^2]。
---
### 实现 SSE 的关键要素
#### 客户端部分
在浏览器中,JavaScript 提供了一个 `EventSource` 对象,用于监听来自服务器的事件流。以下是创建 `EventSource` 并处理接收到的消息的基本语法:
```javascript
const eventSource = new EventSource('/stream');
eventSource.onmessage = function(event) {
console.log('New message:', event.data);
};
eventSource.onerror = function(err) {
console.error('Error occurred:', err);
};
```
#### 服务端部分
服务端需要返回带有特殊 MIME 类型 (`text/event-stream`) 的响应头,并按照 SSE 的格式发送数据。以下是一个通用的服务端响应结构:
```http
HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
Access-Control-Allow-Origin: *
```
每条消息应遵循如下格式:
```
id: <id>\n
event: <event-name>\n
data: <json-data>\n\n
```
其中:
- `id`: 消息唯一标识符(可选)。
- `event`: 自定义事件名(可选)。
- `data`: 要发送的实际数据。
---
### 使用 Go 实现 SSE 示例
以下是在 Go 中实现 SSE 的简单示例代码:
```go
package main
import (
"fmt"
"net/http"
"time"
)
func streamHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
for i := 0; ; i++ {
fmt.Fprintf(w, "data: Message %d at %v\n\n", i, time.Now())
w.(http.Flusher).Flush()
time.Sleep(1 * time.Second)
}
}
func main() {
http.HandleFunc("/stream", streamHandler)
err := http.ListenAndServe(":8080", nil)
if err != nil {
panic(err)
}
}
```
此代码启动了一个简单的 SSE 流服务,在 `/stream` 路径下不断发送带有时戳的消息。
---
### 使用 Spring Boot 实现 SSE 示例
如果使用 Java 和 Spring Boot,则可通过控制器中的 `TextEventStream` 返回值轻松实现 SSE 功能。下面是一个完整的例子:
```java
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
@RestController
public class SseController {
@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamEvents() {
return Flux.interval(Duration.ofSeconds(1))
.map(sequence -> LocalDateTime.now() + " : " + sequence);
}
}
```
在此示例中,Spring Boot 利用了反应式编程库 `Flux` 来生成定时器触发的消息流[^2]。
---
### 总结
无论是使用 Go 还是 Spring Boot,SSE 都能以较低复杂度实现实时数据推送的功能。对于只需要单向通信且不需要 WebSocket 复杂性的应用场景来说,SSE 是一个非常合适的选择。
---
阅读全文
相关推荐


















