两个需求:
对于第一个需求,设置了 client.Transport,并在合适的位置调用其 CancelRequest()接口; 对于第二个需求,设置了 client.Timeout ;
但是调试中发现,如果设置了 client.Timeout,则 Transport.CancelRequest()就不再起效。 注释掉 Timeout 就可以生效。
代码如下:
package main
import (
"fmt"
"net/http"
"time"
)
func main() {
trans := &http.Transport{}
client := &http.Client{
Transport: trans,
Timeout: time.Second * (30), // 这一行不注释就无法 CancelRequest
}
req, err := http.NewRequest("GET", "https://www.google.com", nil)
if err != nil {
panic(err)
}
go func() {
time.Sleep(time.Second * time.Duration(1))
fmt.Printf("%v: abort\n", time.Now())
trans.CancelRequest(req)
}()
fmt.Printf("%v: start ...\n", time.Now())
_, err = client.Do(req)
fmt.Printf("%v: done\n", time.Now())
if err != nil {
fmt.Println(err.Error())
}
}
请问我该怎么办?
1
howellz OP 对了,自己不希望用 Timeou 来调用 CanceRequest,还是希望用 client 自己的 timeout 可以么?
|
2
guonaihong 2020-06-22 16:04:35 +08:00
了解下 WithContext 。我在 gout 里面的超时就是用这个 API 实现的。context 可超时取消,可以调用 cancel 取消。
这是官方 WithContext 的文档 https://golang.google.cn/pkg/net/http/#Request.WithContext ## 这是 gout 里面使用 WithContext 的例子 https://github.com/guonaihong/gout/blob/master/_example/05b-cancel.go |
3
SingeeKing 2020-06-22 16:20:58 +08:00
Deprecated: Use Request.WithContext to create a request with a cancelable context instead
|
4
reus 2020-06-22 20:56:15 +08:00
|
5
howellz OP 谢谢各位的回复,我找到了一个比较简单的方法:
``` c := make(chan struct{}) req.Cancel = c go func() { time.Sleep(time.Second * time.Duration(1)) fmt.Printf("%v: abort\n", time.Now()) //trans.CancelRequest(req) close(c) // 用这句取代 CancelRequest }() ``` |