在内置的http NewRequest上设置超时的最佳方法是什么?目前,我正在使用http.Client
.超时涵盖了整个交换,但是是否有更好的方法,例如context.WithDeadline
或context.WithTimeout
.如果是,它是如何工作的,我如何为http.NewRequest
设置context.WithDeadline
解决方案?
有我目前的解决方案:
func (c *Client) post(resource string, data url.Values, timeout time.Duration) ([]byte, error) {
url := c.getURL(resource)
client := &http.Client{
Timeout: timeout * time.Millisecond,
}
req, err := http.NewRequest("POST", url, strings.NewReader(data.Encode()))
if err != nil {
return nil, err
}
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
resp, err := client.Do(req)
if err != nil {
return nil, err
}
return ioutil.ReadAll(resp.Body)
}
从上下文中获取新的上下文。有截止日期。请参阅文档。 WithTimeout 只返回 WithDeadline(parent, time.现在((。添加(超时((。
package main
import (
"context"
"io"
"log"
"net/http"
"os"
"time"
)
func getContent(ctx context.Context) {
req, err := http.NewRequest("GET", "http://example.com", nil)
if err != nil {
log.Fatal(err)
}
ctx, cancel := context.WithDeadline(ctx, time.Now().Add(3 * time.Second))
defer cancel()
req.WithContext(ctx)
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
io.Copy(os.Stdout, resp.Body)
}
func main() {
ctx := context.Background()
getContent(ctx)
}
如果要在主服务器上设置取消触发器:
func main() {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
sc := make(chan os.Signal, 1)
signal.Notify(sc, os.Interrupt)
go func(){
<-sc
cancel()
}()
getContent(ctx)
}