https://github.com/gin-contrib/sse Server-Send Events
这个项目是Server-Send Events
协议的Go语言实现,有关Server-Send Events
的知识,可以参看这几个链接:谷歌HTML5项目网站一篇精彩介绍 和 阮一峰的中文教程 ,这是HTML5
的一个技术规范,用于服务器向浏览器单向推送消息,相对于Websocket
协议,更简单和轻量化。
这个项目被用在了Gin框架之中,用来实现Gin对SSE的支持(c.SSEvent()
)。具体可以参看Gin框架源码中实时聊天高级示例 的代码。
下面简单分析和记录一下这个库的工作原理。
Gin中提供了一个方法,支持返回SSEvent
数据,返回的是一个sse.Event
:
// SSEvent writes a Server-Sent Event into the body stream.
func (c *Context) SSEvent(name string, message interface{}) {
c.Render(-1, sse.Event{
Event: name,
Data: message,
})
}
这个返回结构就是gin-contrib/sse
库中定义的,并且实现了Render接口的两个方法。
Gin中Render接口定义:
type Render interface {
Render(http.ResponseWriter) error
WriteContentType(w http.ResponseWriter)
}
sse中Event结构定义:
type Event struct {
Event string
Id string
Retry uint
Data interface{}
}
sse中Event实现Render接口:
func (r Event) Render(w http.ResponseWriter) error {
r.WriteContentType(w)
return Encode(w, r)
}
func (r Event) WriteContentType(w http.ResponseWriter) {
header := w.Header()
header["Content-Type"] = contentType
if _, exist := header["Cache-Control"]; !exist {
header["Cache-Control"] = noCache
}
}
sse中实现SSE协议约定(可参看SSE的协议说明):
const ContentType = "text/event-stream"
var contentType = []string{ContentType}
var noCache = []string{"no-cache"}
var fieldReplacer = strings.NewReplacer(
"\n", "\\n",
"\r", "\\r")
var dataReplacer = strings.NewReplacer(
"\n", "\ndata:",
"\r", "\\r")
sse中实现SSE协议约定(这几个函数可以看源码,按照SSE协议写数据):
func Encode(writer io.Writer, event Event) error {
w := checkWriter(writer)
writeId(w, event.Id)
writeEvent(w, event.Event)
writeRetry(w, event.Retry)
return writeData(w, event.Data)
}
sse库中还有一个sse-decoder.go
,貌似在Gin里面没用上,因为SSE协议是服务器向浏览器单向推送,单工通道,目前应该用不上解码数据吧。