golang实现HTML服务器推送事件的客户端与服务端插件库go-sse的使用
Golang实现HTML服务器推送事件的客户端与服务端插件库go-sse的使用
go-sse简介
go-sse是一个提供服务器推送事件(Server-Sent Events)实现的Golang包,它符合WHATWG HTML规范第9.2节的要求,适合需要连接到SSE服务器端点或向前端服务提供事件的应用程序。
特性
- 包中每个类型和方法都有完整的文档
- 符合WHATWG HTML规范
- 广泛的测试套件确保一致性
go-sse要求最低Go 1.18版本。
基本用法
首先导入包:
import "github.com/lampctl/go-sse"
作为客户端使用
创建客户端:
// 从URL创建客户端配置
cfg, err := sse.NewClientConfigFromURL("http://example.com/sse")
if err != nil {
// 处理错误
}
// 创建客户端
c := sse.NewClient(cfg)
从c.Events
通道读取事件:
for e := range c.Events {
fmt.Println("Event received!")
fmt.Println(e.Data)
}
注意:如果连接关闭或中断,客户端将根据规范尝试重新连接,并从中断处继续返回事件。这都在后台处理,不会影响事件通道的状态。
完成后关闭客户端:
c.Close()
作为服务器使用
服务器组件通过实现http.Handler
的Handler
提供:
// 创建默认配置的处理器
h := sse.NewHandler(nil)
// 或者自定义初始化配置
h := sse.NewHandler(&sse.HandlerConfig{
NumEventsToKeep: 10, // 保留的事件数量
ChannelBufferSize: 4, // 通道缓冲区大小
})
发送事件:
h.Send(&sse.Event{
Type: "alert", // 事件类型
Data: "The aliens are invading!", // 事件数据
ID: "12345", // 事件ID
})
完成后关闭处理器:
h.Close()
完整示例
服务端示例
package main
import (
"fmt"
"net/http"
"time"
"github.com/lampctl/go-sse"
)
func main() {
// 创建SSE处理器
h := sse.NewHandler(nil)
// 设置HTTP路由
http.Handle("/events", h)
// 启动HTTP服务器
go http.ListenAndServe(":8080", nil)
// 每秒发送一个事件
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
count := 0
for range ticker.C {
count++
h.Send(&sse.Event{
Type: "message",
Data: fmt.Sprintf("Event %d", count),
ID: fmt.Sprintf("%d", count),
})
}
}
客户端示例
package main
import (
"fmt"
"log"
"github.com/lampctl/go-sse"
)
func main() {
// 创建客户端配置
cfg, err := sse.NewClientConfigFromURL("http://localhost:8080/events")
if err != nil {
log.Fatal(err)
}
// 创建客户端
c := sse.NewClient(cfg)
defer c.Close()
// 接收事件
for e := range c.Events {
fmt.Printf("Received event: %+v\n", e)
}
}
这个示例展示了如何使用go-sse库创建SSE服务器和客户端。服务端每秒发送一个事件,客户端接收并打印这些事件。
更多关于golang实现HTML服务器推送事件的客户端与服务端插件库go-sse的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang实现HTML服务器推送事件的客户端与服务端插件库go-sse的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用go-sse实现HTML服务器推送事件(SSE)
SSE(Server-Sent Events)是一种允许服务器向客户端推送数据的Web技术,它基于HTTP协议,使用简单且高效。下面我将介绍如何使用go-sse库在Golang中实现SSE的客户端和服务端。
安装go-sse库
首先安装go-sse库:
go get github.com/tmaxmax/go-sse
服务端实现
基本服务端示例
package main
import (
"fmt"
"net/http"
"time"
"github.com/tmaxmax/go-sse"
)
func main() {
// 创建SSE服务
s := sse.NewService()
// 创建事件发布器
publisher := s.NewPublisher("updates")
// 启动一个goroutine定期发送事件
go func() {
for i := 0; ; i++ {
// 构造事件
event := sse.Event{
ID: fmt.Sprintf("%d", i),
Event: "message",
Data: []byte(fmt.Sprintf("当前时间: %v", time.Now().Format(time.RFC3339))),
}
// 发布事件
publisher.Publish(event)
// 每秒发送一次
time.Sleep(time.Second)
}
}()
// 设置HTTP路由
http.Handle("/events", s)
// 启动HTTP服务器
fmt.Println("SSE服务器运行在 http://localhost:8080/events")
http.ListenAndServe(":8080", nil)
}
高级功能
- 自定义连接处理
s := sse.NewService(sse.WithConnectionTTL(5*time.Minute))
- 跨域支持
s := sse.NewService(sse.WithCORS(sse.CORS{
Origins: []string{"*"},
Methods: []string{"GET"},
AllowedHeaders: []string{"Content-Type"},
}))
- 认证和鉴权
http.Handle("/events", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 检查认证
if r.Header.Get("Authorization") != "Bearer secret" {
w.WriteHeader(http.StatusUnauthorized)
return
}
// 处理SSE连接
s.ServeHTTP(w, r)
}))
客户端实现
基本客户端示例
package main
import (
"fmt"
"log"
"github.com/tmaxmax/go-sse"
)
func main() {
// 创建客户端
client := sse.NewClient("http://localhost:8080/events")
// 订阅事件
subscription := client.Subscribe("updates")
// 处理接收到的消息
for {
select {
case event := <-subscription.Events:
fmt.Printf("收到事件: ID=%s, 类型=%s, 数据=%s\n",
event.ID, event.Name, string(event.Data))
case err := <-subscription.Errors:
log.Printf("发生错误: %v\n", err)
return
}
}
}
高级客户端功能
- 自定义HTTP客户端
client := sse.NewClient("http://localhost:8080/events",
sse.WithHTTPClient(&http.Client{
Timeout: 10 * time.Second,
}),
)
- 重试策略
client := sse.NewClient("http://localhost:8080/events",
sse.WithRetryPolicy(func(statusCode int, err error) time.Duration {
if statusCode == http.StatusTooManyRequests {
return 30 * time.Second
}
return 5 * time.Second
}),
)
- 自定义头部
client := sse.NewClient("http://localhost:8080/events",
sse.WithHeaders(map[string]string{
"Authorization": "Bearer token",
"X-Custom-Header": "value",
}),
)
实际应用场景
实时日志监控
// 服务端
func logStreamHandler(w http.ResponseWriter, r *http.Request) {
publisher := sseService.NewPublisher("logs")
// 模拟日志流
go func() {
for {
logEntry := generateLogEntry() // 生成日志条目
event := sse.Event{
Event: "log",
Data: []byte(logEntry),
}
publisher.Publish(event)
time.Sleep(500 * time.Millisecond)
}
}()
sseService.ServeHTTP(w, r)
}
实时数据仪表盘
// 客户端
func main() {
client := sse.NewClient("http://localhost:8080/metrics")
// 订阅多个事件类型
metricsSub := client.Subscribe("cpu", "memory", "network")
for {
select {
case event := <-metricsSub.Events:
switch event.Name {
case "cpu":
updateCPUUsage(string(event.Data))
case "memory":
updateMemoryUsage(string(event.Data))
case "network":
updateNetworkStats(string(event.Data))
}
case err := <-metricsSub.Errors:
log.Println("连接错误:", err)
return
}
}
}
注意事项
- 连接管理:SSE连接是长连接,需要妥善处理断开和重连
- 性能考虑:大量并发连接会消耗服务器资源
- 浏览器兼容性:现代浏览器都支持SSE,但IE不支持
- 安全性:确保敏感数据通过HTTPS传输,并实施适当的认证机制
go-sse库提供了简单而强大的SSE实现,适合需要服务器向客户端实时推送数据的应用场景。