[英]How to return from an http handler when the request is cancelled or times out
I'm doing sse , the important code is: 我正在做sse ,重要的代码是:
var clientes=new(sync.Map)
type canalesStruct struct{
sender chan []byte
close chan bool
}
func (broker *brokerStruct) ServeHTTP(w http.ResponseWriter, r *http.Request) {
flusher, ok := w.(http.Flusher)
if !ok {
http.Error(w, "Streaming unsupported!", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
var ID string
//Get the ID somehow
canales:=new(canalesStruct)
canales.sender=make(chan []byte)
canales.close=make(chan bool)
clientes.store(ID,canales)
notify := w.(http.CloseNotifier).CloseNotify()
defer func() {
clientes.Delete(ID)
}()
for {
select {
case <-notify:
return
case <-canales.close:
return
case data:= <-canales.sender:
fmt.Fprintf(w, "data: %s\n\n",data)
flusher.Flush()
}
}
}
func sendDataToChanelID(ID string,data []byte){
canalesRaw,_:=clientes.Load(ID)
canales,_:=canalRaw(*canalesStruct)
canales.sender <-data
}
So I have two question over there: 所以我在那边有两个问题:
A simple way to return different values depending on timing is to wait on a channel. 根据时序返回不同值的一种简单方法是在通道上等待。
func F() int {
// channel to receive info
c := make(chan int)
// start timeout goroutine
go func() {
time.Sleep(TIMEOUT)
c <- -1
}()
// start work goroutine
go func() {
c <- GetValue()
}()
// receive value
x := <-c
// start goroutine to discard late value
go func() {
_ = <-c
}()
// return received value
return x
}
So, the two goroutines are racing each other. 因此,两个goroutine相互竞争。 If the timeout gets there first, the value is -1. 如果超时首先到达那里,则值为-1。
I beleive a call to fmt.Fprintf()
will just fail when the underlying HTTP request closes. 我相信对fmt.Fprintf()
的调用fmt.Fprintf()
在基础HTTP请求关闭时失败。
"To fail" here means it will return a non-nil error. 这里的“失败”表示它将返回非空错误。
So, to properly handle the case of HTTP request being shut down, check the error return of fmt.Fprintf()
, like in 因此,要正确处理HTTP请求被关闭的情况,请检查fmt.Fprintf()
的错误返回,例如
_, err := fmt.Fprintf(w, ...)
if err != nil {
// We have failed to write to the underlying connection
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.