Go Transport
在Go 对HTTP POST的支持中,简单介绍了客户端的定义。其中结构体Client
有一个字段Transport
,它用来定义单个HTTP
请求的机制,如果为nil
,则使用默认的DefaultTransport
。下面是Transport
的默认实现,由DefaultClient
使用。它根据需要来建立网络连接,然后将其缓存,供后续调用重用。它可以使用HTTP
代理,例如根据$HTTP_PROXY
和$NO_PROXY
环境变量指定。
var DefaultTransport RoundTripper = &Transport{Proxy: ProxyFromEnvironment,DialContext: (&net.Dialer{Timeout: 30 * time.Second,KeepAlive: 30 * time.Second,DualStack: true,}).DialContext,MaxIdleConns: 100,IdleConnTimeout: 90 * time.Second,TLSHandshakeTimeout: 10 * time.Second,ExpectContinueTimeout: 1 * time.Second,
}
默认的Transport
指定了六个字段,各个字段的意思接下来将会解说。单从这几个字段的字面大致可以看出,设置的多是超时的时间。而这些值默认情况下都比较大,所以有必要自己重新定义一个Transport
。
type Transport struct {idleMu sync.MutexwantIdle bool idleConn map[connectMethodKey][]*persistConn idleConnCh map[connectMethodKey]chan *persistConnidleLRU connLRUreqMu sync.MutexreqCanceler map[*Request]func(error)altMu sync.Mutex altProto atomic.ValueconnCountMu sync.MutexconnPerHostCount map[connectMethodKey]intconnPerHostAvailable map[connectMethodKey]chan struct{}//Proxy指定一个函数来返回给定请求的代理Proxy func(*Request) (*url.URL, error)//DialContext指定用于创建未加密的TCP连接的拨号功能,如果值为nil,则传输使用net包拨号。此方法返回一个Conn接口DialContext func(ctx context.Context, network, addr string) (net.Conn, error)// Dial指定用于创建未加密的TCP连接的拨号功能,现在已经被DialContext取代,通过后者可以在不需要的时候取消拨号。如果这两个字段都设置了,那么DialContext的优先级高于DialDial func(network, addr string) (net.Conn, error)// DialTLS指定可选的拨号功能,用于为非代理的HTTPS请求创建TLS连接,如果值为nil,那么使用Dial和TLSClientConfig。如果设置了值,那么拨号将忽略TLSClientConfig和TLSHandshakeTimeout,假设返回的net.Conn已经通过TLS握手。DialTLS func(network, addr string) (net.Conn, error)TLSClientConfig *tls.Config// TLSHandshakeTimeout定义TLS握手等待的最大时间,0表示没有超时TLSHandshakeTimeout time.Duration//DisableKeepAlives如果为true,则禁用HTTP的keep-alive,并且仅使用与服务器的连接来获取单个HTTP请求DisableKeepAlives bool//DisableCompression如果为true,则阻止对响应body进行压缩 DisableCompression bool//控制所有主机上的最大空闲连接数,零意味着没有限制MaxIdleConns intMaxIdleConnsPerHost intMaxConnsPerHost int//IdleConnTimeout是长连接在关闭之前,保持空闲的最长时间,零表示没有限制IdleConnTimeout time.Duration//ResponseHeaderTimeout如果非零,则指定在完全写入请求之后,等待服务器响应header的时间量,这个时间不包括读取响应body的时间ResponseHeaderTimeout time.Duration//ExpectContinueTimeout定义等待服务器的第一个响应headers的时间,0表示没有超时,则body会立刻发送,无需等待服务器批准,这个时间不包括发送请求header的时间ExpectContinueTimeout time.DurationTLSNextProto map[string]func(authority string, c *tls.Conn) RoundTripper//ProxyConnectHeader是可选参数,指定在CONNECT请求期间发送给代理的headers ProxyConnectHeader Header//MaxResponseHeaderBytes指定服务器响应头中允许的响应字节数限制,0表示使用默认限制MaxResponseHeaderBytes int64nextProtoOnce sync.Onceh2transport h2Transport // non-nil if http2 wired up
}
凡是默认Transport
用到的字段都在上面加了注释,其中DialContext
字段有两种方法。
第一种是采用DefaultTransport
中那样的方式定义,首先定义一个Dialer
结构体,然后再其上调用DialContext
接口。
Dialer
包含连接地址的一些选项,每个字段的零值相当于没有该选项的拨号,因此Dialer
为零值等同于直接调用Dial
功能。
type Dialer struct {//Timeout是拨号等待连接完成的最长时间,如果还设置了Deadline,那么可能会提前失败,默认是没有超时,使用TCP拨号到多个IP地址的主机名时,可以在它们之间划分超时。即使有或没有Timeout,操作系统也会强加自己的超时时间,例如,TCP超时的时间一般在3sTimeout time.Duration//Deadline是拨号失败的绝对时间点,零表示没有截止日期,或者与Timeout选项一样依赖于操作系统Deadline time.TimeLocalAdddr Addr//是否启动dual-stack状态,启用下,会优先选择IPv6连线,如果失败,再尝试IPv4连线DualStack bool//FallbackDelay指定在启用DualStack时生成回退连接之前等待的时间长度,如果为0,使用默认延迟300msFallbackDelay time.Duration//KeepAlive指定保持活动网络连接的时间,如果为0,则不启用keep-alive,不支持keep-alive的网络协议会忽略此字段KeepAlive time.DurationResolver *ResolverCancel <-chan struct{}//Control如果不是nil,则在创建网络连接后,实际拨号之前调用它Control func(network, address string, c syscall.RawConn) error
}
下面看Dialer
结构体上的接口,DialContext
使用提供的context
连接到指定网络上的地址。提供的context
必须非nil
,如果上下文在连接完成之前到期,那么返回错误。成功连接后,context
的任何过期都不会影响连接。
func (d *Dialer) DialContext(ctx context.Context, network, address string) (Conn, error) {/*...*/
}
标准包中使用的方法,直接在自定义的Dialer
上调用DialContext
接口。
client := &http.Client{Transport: &http.Transport{DialContext: (&net.Dialer{Timeout: 3 * time.Second,KeepAlive: 10 * time.Second,DualStack: true,}).DialContext,MaxIdleConns: 100,IdleConnTimeout: 5 * time.Second,TLSHandshakeTimeout: 1 * time.Mill}
}
另外一种是直接生成函数的方法,但是这种方法不推荐,比较复杂。思路也是先生成自定义的Dialer
结构体,然后在其上调用Dial
方法。实质上也是在Dialer
上调用DialContext
方法。例如:
client := &http.Client{Transport: &http.Transport{DialContext: func(ctx context.Context, network, addr string) (net.Conn, err error) {c, err := net.DialTimeout(network, addr, time.Second * 3)if err != nil {return nil, err}return c, nil}}
}
之所以上面说调用Dial
方法实质上也是在Dialer
上调用DialContext
方法,原因如下:
func DialTimeout(network, address string, timeout time.Duration) (Conn, error) {d := Dialer {Timeout: timeout,}return d.Dial(network, address)
}
来看看Dial
接口的定义
func (d *Dialer) Dial(network, address string) (Conn, error) {return d.DialContext(context.Background(), network, address)
}
Go Transport相关推荐
- ecshop transport.js/run() error:undefined
在使用ECshop的AJAX(即:transport.js) IE有时候会出现:ReferenceError: process_request is not defined,FF则出现:transpo ...
- 警惕!新版Net Transport(影音传送带)安装有猫腻
http://article.pcpop.com/show.aspx?topic_id=1317935 由于早些时候FlashGet和NetAnts(网络蚂蚁)迟迟没有新版本发布,Net Transp ...
- 【Netty】传输(Transport)
传输(Transport) 在网络中传递的数据总是具有相同的类型:字节. 这些字节流动的细节取决于网络传输,它是一个帮我们抽象 底层数据传输机制的概念,我们不需要关心字节流动的细节,只需要确保字节被可 ...
- ActiveMQ Transport Connectors
一,介绍 ActiveMQ的Transport Connectors 是什么? ActiveMQ是一个消息服务器.作为消息服务器,就会有生产者和消费者来使用它.生产者将消息发送给ActiveMQ,消费 ...
- ES transport client批量导入
从bulk.txt文件中按行读取,然后bulk导入.首先通过调用client.prepareBulk()实例化一个BulkRequestBuilder对象,调用BulkRequestBuilder对象 ...
- org.apache.activemq.transport.InactivityIOException: Cannot send, channel has already failed
项目是使用activeMQ 发布订阅的模式,在本地测试正常,但是 放到服务器上出现这个错误: org.apache.activemq.transport.InactivityIOException: ...
- WCF wsHttpBinding之Transport security Mode, clientCredentialType=”Basic”
如何在WCF中使用Transport Security Mode,以及如何创建证书,请参见<WCF basicHttpBinding之Transport Security Mode, clien ...
- WCF NetTcpBinding Transport安全模式(6) ClientCredentialType证书验证模式---- PeerTrust验证模式...
WCF NetTcpBinding Transport安全模式(6) ClientCredentialType证书验证模式---- PeerTrust验证模式 当证书验证模式设置为"Pe ...
- ES使用org.elasticsearch.client.transport.NoNodeAvailableException: No node available 错误解决方法
ES使用org.elasticsearch.client.transport.NoNodeAvailableException: No node available 错误解决方法 参考文章: (1)E ...
- transport=websocket' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
异常1: transport=websocket' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED 这个原 ...
最新文章
- 恭喜CocoStudio 1.5和Mac版本发布
- 网站推广专员浅析高指数关键词优化网站推广如何推至首页?
- 面试必问:常用的加密算法有哪些?
- 解决TreeView中使用JavaScript完成CheckBox全选的办法
- java抽象类到底能不能够实例化?
- 0326互联网新闻 | 字节跳动推出阅读产品番茄小说;微信正式上线物流助手接口功能...
- Can't locate SVN/Core.pm in @INC (you may need to install the SVN::Core module)报错
- C#里Attribute属性
- 永远和靠谱的人在一起!
- 酱油和gbt酱油哪个好_酱油不是越贵越好,聪明人才知道的两个选酱油小技巧
- rabbitmq安装centos7
- linux db2在线备份,DB2 pureScale在线备份恢复实例
- shell命令行快捷键
- #简单统计学#加权平均数
- 写的将skb copy/clone后转发到源地址的一段代码
- AID Learning 0.87F3安装注意事项
- java d打字游戏_练习--java实现的打字游戏
- Skia深入分析6——skia中图像编解码代码概述
- Linux 文件/文件夹无法删除问题解决方案
- BCompare报Revoked错误不能打开的解决方法