服務(wù)器端接口
package main
import (
"fmt"
"log"
"math/rand"
"net/http"
"time"
)
// 定義User結(jié)構(gòu)
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Age int `json:"age"`
}
func SSEHandler(w http.ResponseWriter, r *http.Request) {
// 設(shè)置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")
// 防止客戶端關(guān)閉導(dǎo)致服務(wù)器崩潰
flusher, ok := w.(http.Flusher)
if !ok {
http.Error(w, "Streaming unsupported!", http.StatusInternalServerError)
return
}
// 創(chuàng)建一個隨機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秒發(fā)送一次更新
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 // 隨機年齡
// 將更新發(fā)送給客戶端
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');
// 創(chuàng)建 EventSource 連接到服務(wù)器的 /user-details 路由
const eventSource = new EventSource("http://127.0.0.1:1217/user-details");
// 監(jiān)聽服務(wù)器推送的數(shù)據(jù)
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>