1
我想知道如何正確地執行/一個HTTP服務器內使用,並實現middleware時使用context.Done()方法,我的目標是取消後續事件時,客戶端斷開連接跨嵌套的中間件。如何使用嵌套HTTP中間件使用context.Done()
爲了測試我創建了下面的代碼,我不知道,如果是這樣做,因爲我不得不創建HandleFunc和goroutine內的channel來處理請求的正確方式,把這個所有一起select內等待聲明。
package main
import (
"fmt"
"log"
"net/http"
"time"
)
func hello(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
log.Println("handler started")
defer log.Println("hander ended")
ch := make(chan struct{})
go func(ch chan struct{}) {
time.Sleep(5 * time.Second)
fmt.Fprintln(w, "Hello")
ch <- struct{}{}
}(ch)
select {
case <-ch:
case <-ctx.Done():
err := ctx.Err()
log.Println(err)
http.Error(w, err.Error(), http.StatusPartialContent)
}
}
func main() {
http.HandleFunc("/", hello)
log.Fatal(http.ListenAndServe(":8080", nil))
}
基本上這裏的請求由睡眠5秒模擬負載,然後打印Hello
,但如果客戶取消該請求,例如:
$ curl 0:8080
再按下CTL + Ç,這將是loged:
2017/07/07 22:22:40 handler started
2017/07/07 22:22:42 context canceled
2017/07/07 22:22:42 hander ended
這工作BU牛逼想知道如果這模式(夠程和選擇)應在每一個嵌套處理程序使用,或者如果有正在實施的更好的方法。:
ch := make(chan struct{})
go func(ch chan struct{}) {
// some logic
ch <- struct{}{}
}(ch)
select {
case <-ch:
case <-ctx.Done():
err := ctx.Err()
log.Println(err)
http.Error(w, err.Error(), http.StatusPartialContent)
}
您通過上下文,但是你還需要創建'選擇{ 情況下<-ch: 情況下<-ctx.Done(): ERR:= ctx.Err () log.Println(err) http.Error(w,err.Error(),http.StatusPartialContent) }'?或者當客戶斷開連接時應如何處理? – nbari
我讀它作爲每個異步過程需要比賽的情況下提前退出。無論如何,在嚴重的應用程序中,您可能需要超時的子環境 – AJcodez
可以請你分享一個例子或者寫一個基本的實現,基本上想知道這個處理器的所有代碼是否在一個goruine中:'go func(ch chan struct {}){....' – nbari