代码之家  ›  专栏  ›  技术社区  ›  PumpkinSeed

设置内置HTTP请求超时的最佳方法

  •  1
  • PumpkinSeed  · 技术社区  · 8 年前

    设置超时的最佳方式是什么 内置的 http.Client 。超时,覆盖整个交换,但是否有更好的方法,例如 context.WithDeadline context.WithTimeout 。如果是,它是如何工作的,如何设置 解决方案 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)
    }
    
    1 回复  |  直到 8 年前
        1
  •  1
  •   mattn    8 年前

    documentation .

    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上执行cancel触发器:

    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)
    }