在内置 http NewRequest上设置超时的最佳方法是什么?目前,我正在使用http.Client
。超时覆盖整个交易所,但有更好的内容,例如context.WithDeadline
或context.WithTimeout
。如果是,它是如何工作的,如何为context.WithDeadline
设置http.NewRequest
解决方案?
我目前的解决方案是:
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)
}
答案 0 :(得分:1)
从context.WithDeadline获取新的上下文。见documentation。 WithTimeout只返回WithDeadline(parent,time.Now()。Add(timeout))。
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)
}
如果你想在main上取消触发:
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)
}