[英]Why does this SSE handler cause the client connection to be stuck in pending?
In this example, https://github.com/kljensen/golang-html5-sse-example/blob/d4eba81ddea2b4191f039adb6929086ca6b39c0f/server.go#L130 , you can block on a channel.在这个例子中, https://github.com/kljensen/golang-html5-sse-example/blob/d4eba81ddea2b4191f039adb6929086ca6b39c0f/server.go#L130 ,你可以在一个频道上屏蔽。 But doing that in my HandleExecute
results in the browser/client connection status to remain stuck in a pending state and nothing gets sent to the client.但是在我的HandleExecute
这样做会导致浏览器/客户端连接状态保持在挂起状态,并且没有任何内容发送到客户端。
If I remove the for loop and use a select statement with a default case writing back no data, then it works ( execute
writes and flushes data) except that the handler returns and the client re-connects every 5 seconds instead of maintaining the connection.如果我删除 for 循环并使用带有默认情况下不回写数据的 select 语句,那么它可以工作( execute
写入和刷新数据),除了处理程序返回并且客户端每 5 秒重新连接而不是维护连接。 When I do it that way, the client gets streamed data only on the reconnect intervals.当我这样做时,客户端仅在重新连接间隔内获取流数据。
So users end up seeing a delay lasting anywhere less than 5 seconds depending on when HandleExecuteRequest
gets hit.因此,根据HandleExecuteRequest
何时被击中,用户最终会看到持续不到 5 秒的延迟。 HandleExecute
could be ready to write but the client may not have reconnected yet. HandleExecute
可能已准备好写入,但客户端可能尚未重新连接。 I hope that makes sense.我希望这是有道理的。
How can I write these handlers to maintain a constant connection instead of reconnecting?我如何编写这些处理程序来保持持续连接而不是重新连接?
func (s *Server) HandleExecuteRequest(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
log.Printf("Error parsing request: %v", err)
fmt.Fprintf(w, "Error parsing request: %v", err)
return
}
decoder := schema.NewDecoder()
var f Form
err = decoder.Decode(&f, r.PostForm)
if err != nil {
log.Printf("Error decoding form: %v", err)
fmt.Fprintf(w, "Error decoding form: %v", err)
return
}
s.clientMap[r.RemoteAddr] <- buildCommand(&f)
}
func (s *Server) HandleExecute(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
s.addClient(r)
for {
cmd := <-s.clientMap[r.RemoteAddr]
execute(w, cmd)
}
}
Javascript Javascript
var source = new EventSource('<host>/execute');
source.onmessage = function(e) {
document.querySelector("code").innerHTML +="<span class='font-weight-bold' style='white-space: pre-wrap; padding-left: 200px;'>" + e.data + "</span>" + "<br>"
};
If I update HandleExecute
to below, I get a continuous connection but then HandleExecuteRequest
gets stuck in pending when that is hit.如果我将HandleExecute
更新到下面,我会得到一个连续的连接,但是当它被击中时HandleExecuteRequest
会卡在挂起状态。 It could how I'm setting up the clients and handling the channels in this case.在这种情况下,这可能是我设置客户端和处理渠道的方式。
func (s *Server) HandleExecute(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
s.addClient(r)
for {
select {
case cmd := <-s.clientMap[r.RemoteAddr]:
execute(w, cmd)
default:
fmt.Fprint(w, ": no data\n\n")
}
}
}
My issue had nothing to do with how the SSE handler was set up.我的问题与 SSE 处理程序的设置方式无关。 My channel was not being setup correctly and was blocking connections.我的频道没有正确设置,并且阻止了连接。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.