Gui*_*meP 9 go server-sent-events
我正在开发基于Twitter主题标签和服务器发送事件的聊天室,包含https://github.com/antage/eventsource
我有一个关于客户端断开的问题.我运行goroutine向客户端发送消息,但是当客户端断开连接时,goroutine仍然运行.
我不知道如何在服务器端检测到客户端已断开连接.
func (sh StreamHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
es := eventsource.New(
&eventsource.Settings{
Timeout: 2 * time.Second,
CloseOnTimeout: true,
IdleTimeout: 2 * time.Second,
Gzip: true,
},
func(req *http.Request) [][]byte {
return [][]byte{
[]byte("X-Accel-Buffering: no"),
[]byte("Access-Control-Allow-Origin: *"),
}
},
)
es.ServeHTTP(resp, req)
go func() {
var id int
for {
id++
time.Sleep(1 * time.Second)
es.SendEventMessage("blabla", "message", strconv.Itoa(id))
}
}()
}
Run Code Online (Sandbox Code Playgroud)
截至 2018 年 12 月,显然 CloseNotifier 已弃用。推荐的解决方案是使用RequestContext。以下对我有用:
done := make(chan bool)
go func() {
<-req.Context().Done()
done <- true
}()
<-done
Run Code Online (Sandbox Code Playgroud)
您可以使用CloseNotifier,它可以让您知道基础的http连接是否已关闭。喜欢:
notify := w.(http.CloseNotifier).CloseNotify()
go func() {
<-notify
// connection close, do cleanup, etc.
}()
Run Code Online (Sandbox Code Playgroud)
高温超导
你可以检查ConsumersCount():
go func() {
var id int
for es.ConsumersCount() > 0 {
id++
es.SendEventMessage("blabla", "message", strconv.Itoa(id))
time.Sleep(1 * time.Second)
}
fmt.Println("closed")
}()
Run Code Online (Sandbox Code Playgroud)
有点老套,但似乎有效。
您可能最好使用不同的包或推出自己的包,这样您就可以更好地控制 goroutine 的生命周期。您可以检测关闭的连接.Write(此包未公开该连接)。
如果您需要,这里有一个 TCP 聊天服务器示例:chat-server。还有一个与之配套的视频教程:教程。
同样的基本模式也适用于 SSE。
| 归档时间: |
|
| 查看次数: |
2384 次 |
| 最近记录: |