package main import ( "context" "fmt" "io/ioutil" "net/http" "sync" "time" ) // respData 是用来记录返回值的结构体 type respData struct { resp *http.Response err error } func doCall(ctx context.Context) { transport := http.Transport{ DisableKeepAlives: true, // 长连接 } client := http.Client{ Transport: &transport, } respChan := make(chan *respData, 1) // 创建一个channel来放返回值 req, err := http.NewRequest("GET", "http://127.0.0.1:8000/", nil) if err != nil { fmt.Printf("new requestg failed, err:%v\n", err) return } req = req.WithContext(ctx) // 将req的context设置为传进来的ctx, 用这个函数给私有属性赋值 var wg sync.WaitGroup wg.Add(1) defer wg.Wait() go func() { resp, err := client.Do(req) // 执行req rd := &respData{ resp: resp, err: err, } respChan <- rd wg.Done() }() select { case <-ctx.Done(): //transport.CancelRequest(req) fmt.Println("请求超时") case result := <-respChan: // 当请求未超时 fmt.Println("请求成功") if result.err != nil { fmt.Printf("请求失败, err:%v\n", result.err) return } defer result.resp.Body.Close() data, _ := ioutil.ReadAll(result.resp.Body) fmt.Printf("请求结果为:%v\n", string(data)) } } func main() { ctx, cancle := context.WithTimeout(context.Background(), time.Millisecond*100) defer cancle() doCall(ctx) }