服务器端接口
package main
import (
"fmt"
"log"
"math/rand"
"net/http"
"time"
)
// 定义User结构
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Age int `json:"age"`
}
func SSEHandler(w http.ResponseWriter, r *http.Request) {
// 设置SSE的必要头部信息
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
// 防止客户端关闭导致服务器崩溃
flusher, ok := w.(http.Flusher)
if !ok {
http.Error(w, "Streaming unsupported!", http.StatusInternalServerError)
return
}
// 创建一个随机User生成器
users := []User{
{ID: 1, Name: "Alice", Age: 30},
{ID: 2, Name: "Bob", Age: 25},
{ID: 3, Name: "Charlie", Age: 28},
}
ticker := time.NewTicker(2 * time.Second) // 每2秒发送一次更新
defer ticker.Stop()
for {
select {
case <-r.Context().Done():
log.Println("Client disconnected")
return
case <-ticker.C:
// 随机选择一个用户信息更新
user := users[rand.Intn(len(users))]
user.Age = rand.Intn(50) + 20 // 随机年龄
// 将更新发送给客户端
fmt.Fprintf(w, "data: {\"id\": %d, \"name\": \"%s\", \"age\": %d}\n\n", user.ID, user.Name, user.Age)
flusher.Flush()
}
}
}
func main() {
http.HandleFunc("/user-details", SSEHandler)
fmt.Println("Starting server at :1217")
log.Fatal(http.ListenAndServe(":1217", nil))
}
HTML 页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SSE Example</title>
</head>
<body>
<h1>User Details Updates</h1>
<div id="output"></div>
<script>
const output = document.getElementById('output');
// 创建 EventSource 连接到服务器的 /user-details 路由
const eventSource = new EventSource("http://127.0.0.1:1217/user-details");
// 监听服务器推送的数据
eventSource.onmessage = function(event) {
const userData = JSON.parse(event.data);
output.innerHTML = `User ID: ${userData.id}, Name: ${userData.name}, Age: ${userData.age}<br>` + output.innerHTML;
};
// 处理错误
eventSource.onerror = function(error) {
console.error("Error:", error);
eventSource.close();
};
</script>
</body>
</html>