sse
sse
sse 中间件为 Flame 实例提供服务器发送事件(Server-Sent Events),用于通过 HTTP 连接向 Web 客户端发送更新。
你可以在 GitHub 上阅读该中间件的源码或通过 pkg.go.dev 查看 API 文档。
下载安装
go get github.com/flamego/sse用法示例
sse.Bind 中间件会将响应配置为事件流,并向后续处理器注入一个带类型的只发送通道。请向 Bind 传递非指针值;传递 T 类型的值会使处理器可以获取 chan<- *T 类型的通道。通过该通道发送的值会被编码为 JSON 事件数据。
以下示例每秒向每个已连接的客户端发送一次当前时间:
package main
import (
"time"
"github.com/flamego/flamego"
"github.com/flamego/sse"
)
type update struct {
Time time.Time `json:"time"`
}
func main() {
f := flamego.Classic()
f.Get("/events", sse.Bind(update{}), func(c flamego.Context, events chan<- *update) {
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for {
select {
case <-c.Request().Context().Done():
return
case now := <-ticker.C:
select {
case events <- &update{Time: now}:
case <-c.Request().Context().Done():
return
}
}
}
})
f.Run()
}客户端可以使用浏览器的 EventSource API 接收事件流:
<p id="time"></p>
<script>
const events = new EventSource("/events");
events.onmessage = (event) => {
const update = JSON.parse(event.data);
document.querySelector("#time").textContent = update.time;
};
</script>路由处理器会在连接的整个生命周期内保持运行。请始终监听 c.Request().Context().Done(),并在客户端断开连接时停止计时器或释放其它资源。
该中间件会定期发送 ping 以保持连接。默认间隔为 10 秒,可以通过 sse.Options 修改:
f.Get("/events",
sse.Bind(update{}, sse.Options{
PingInterval: 30 * time.Second,
}),
func(c flamego.Context, events chan<- *update) {
// 在请求上下文被取消之前持续生成事件。
},
)