golang的Context
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)
}