在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相关推荐

  1. ecshop transport.js/run() error:undefined

    在使用ECshop的AJAX(即:transport.js) IE有时候会出现:ReferenceError: process_request is not defined,FF则出现:transpo ...

  2. 警惕!新版Net Transport(影音传送带)安装有猫腻

    http://article.pcpop.com/show.aspx?topic_id=1317935 由于早些时候FlashGet和NetAnts(网络蚂蚁)迟迟没有新版本发布,Net Transp ...

  3. 【Netty】传输(Transport)

    传输(Transport) 在网络中传递的数据总是具有相同的类型:字节. 这些字节流动的细节取决于网络传输,它是一个帮我们抽象 底层数据传输机制的概念,我们不需要关心字节流动的细节,只需要确保字节被可 ...

  4. ActiveMQ Transport Connectors

    一,介绍 ActiveMQ的Transport Connectors 是什么? ActiveMQ是一个消息服务器.作为消息服务器,就会有生产者和消费者来使用它.生产者将消息发送给ActiveMQ,消费 ...

  5. ES transport client批量导入

    从bulk.txt文件中按行读取,然后bulk导入.首先通过调用client.prepareBulk()实例化一个BulkRequestBuilder对象,调用BulkRequestBuilder对象 ...

  6. org.apache.activemq.transport.InactivityIOException: Cannot send, channel has already failed

    项目是使用activeMQ 发布订阅的模式,在本地测试正常,但是 放到服务器上出现这个错误: org.apache.activemq.transport.InactivityIOException: ...

  7. WCF wsHttpBinding之Transport security Mode, clientCredentialType=”Basic”

    如何在WCF中使用Transport Security Mode,以及如何创建证书,请参见<WCF basicHttpBinding之Transport Security Mode, clien ...

  8. WCF NetTcpBinding Transport安全模式(6) ClientCredentialType证书验证模式---- PeerTrust验证模式...

    WCF NetTcpBinding Transport安全模式(6)   ClientCredentialType证书验证模式---- PeerTrust验证模式 当证书验证模式设置为"Pe ...

  9. ES使用org.elasticsearch.client.transport.NoNodeAvailableException: No node available 错误解决方法

    ES使用org.elasticsearch.client.transport.NoNodeAvailableException: No node available 错误解决方法 参考文章: (1)E ...

  10. transport=websocket' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED

    异常1: transport=websocket' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED 这个原 ...

最新文章

  1. 恭喜CocoStudio 1.5和Mac版本发布
  2. 网站推广专员浅析高指数关键词优化网站推广如何推至首页?
  3. 面试必问:常用的加密算法有哪些?
  4. 解决TreeView中使用JavaScript完成CheckBox全选的办法
  5. java抽象类到底能不能够实例化?
  6. 0326互联网新闻 | 字节跳动推出阅读产品番茄小说;微信正式上线物流助手接口功能...
  7. Can't locate SVN/Core.pm in @INC (you may need to install the SVN::Core module)报错
  8. C#里Attribute属性
  9. 永远和靠谱的人在一起!
  10. 酱油和gbt酱油哪个好_酱油不是越贵越好,聪明人才知道的两个选酱油小技巧
  11. rabbitmq安装centos7
  12. linux db2在线备份,DB2 pureScale在线备份恢复实例
  13. shell命令行快捷键
  14. #简单统计学#加权平均数
  15. 写的将skb copy/clone后转发到源地址的一段代码
  16. AID Learning 0.87F3安装注意事项
  17. java d打字游戏_练习--java实现的打字游戏
  18. Skia深入分析6——skia中图像编解码代码概述
  19. Linux 文件/文件夹无法删除问题解决方案
  20. BCompare报Revoked错误不能打开的解决方法

热门文章

  1. 做网站是否一定需要seo
  2. 如何修改达梦数据目录路径
  3. PS常用美化处理方法大全
  4. php对接臻识摄像机
  5. Thymeleaf了解
  6. Could not autowire field: private com.xxx.dao(已解决)
  7. 次世代建模师电脑里面收藏的素材
  8. 原创: 莫叹人间苦与乐,天下何处无净境
  9. Python中String方法的使用
  10. echarts之河南省市地图(根据数据大小控制颜色显示变化)