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