返回顶部
首页 > 资讯 > 精选 >Go中http client的示例分析
  • 467
分享到

Go中http client的示例分析

2023-06-15 00:06:38 467人浏览 安东尼
摘要

这篇文章给大家分享的是有关Go中Http client的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。什么是gogo是golang的简称,golang 是Google开发的一种静态强类型、编译型、并发型,

这篇文章给大家分享的是有关GoHttp client的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

什么是go

go是golang的简称,golang 是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言,其语法与 C语言相近,但并不包括如枚举、异常处理、继承、泛型、断言、虚函数等功能。

      

http client

go封装了http客户端,请求远程数据非常方便,看些源码底层如何实现。

resp, err := http.Get("https://baidu.com") if err != nil {    fmt.Printf("发起请求失败:%v", err)    return }defer resp.Body.Close() io.Copy(os.Stdout, resp.Body)

请求的大致流程

1.根据请求条件,构建request对象

2.所有的client请求,都会经过client.do()处理

func (c *Client) do(req *Request) (retres *Response, reterr error)
2.1 request请求使用client.send()处理
func (c *Client) send(req *Request, deadline time.Time) (resp *Response, didTimeout func() bool, err error)resp, didTimeout, err = send(req, c.transport(), deadline)//默认传DefaultTransport

3.send函数

func send(ireq *Request, rt RoundTripper, deadline time.Time) (resp *Response, didTimeout func() bool, err error) {    resp, err = rt.RoundTrip(req) }

4.DefaultTransport的RoundTrip方法,实际就是Transport的RoundTrip方法

func (t *Transport) roundTrip(req *Request) (*Response, error) {    treq := &transportRequest{Request: req, trace: trace} //封装新的request    cm, err := t.connectMethodForRequest(treq)    pconn, err := t.getConn(treq, cm) //使用连接池技术,获取连接对象*persistConn,    resp, err = pconn.roundTrip(treq) //使用连接对象获取response}

5.使用连接池技术,获取连接对象*persistConn

func (t *Transport) getConn(treq *transportRequest, cm connectMethod) (pc *persistConn, err error) {    w := &wantConn{ //构建连接对象        cm:         cm,        key:        cm.key(),        ctx:        ctx,        ready:      make(chan struct{}, 1),        beforeDial: testHookPrePendingDial,        afterDial:  testHookPostPendingDial,    }    if delivered := t.queueForIdleConn(w); delivered {//从连接池获取符合的连接对象,有就返回        pc := w.pc                return pc, nil    }        t.queueForDial(w)//发起连接    select {    case <-w.ready:    //连接准备好,就返回连接对象            return w.pc, w.err}
5.1 Transport.queueForDial发起连接
func (t *Transport) queueForDial(w *wantConn) {    go t.dialConnFor(w)}
5.2 发起拨号dialConnFor
func (t *Transport) dialConnFor(w *wantConn) {    pc, err := t.dialConn(w.ctx, w.cm) //发起拨号,返回连接对象    delivered := w.tryDeliver(pc, err)}
5.3 发起拨号
func (t *Transport) dialConn(ctx context.Context, cm connectMethod) (pconn *persistConn, err error) {    pconn = &persistConn{ //构建连接对象        t:             t,        cacheKey:      cm.key(),        reqch:         make(chan requestAndChan, 1),        writech:       make(chan writeRequest, 1),        closech:       make(chan struct{}),        writeErrCh:    make(chan error, 1),        writeLoopDone: make(chan struct{}),    }    conn, err := t.dial(ctx, "tcp", cm.addr()) //tcp连接,获取到net.conn对象    pconn.br = bufio.NewReaderSize(pconn, t.readBufferSize())//可以从conn读    pconn.bw = bufio.NewWriterSize(persistConnWriter{pconn}, t.writeBufferSize())//写到conn    go pconn.readLoop()//开启读协程    go pconn.writeLoop()//开启写协程    return pconn, nil}
5.4读协程,虽然是for循环,但是一次性就把请求的response读完了,如果没有关闭,就会造成协程泄露了
func (pc *persistConn) readLoop() {    alive := true    for alive {        rc := <-pc.reqch //读取request,写入的地方在步骤6        resp, err = pc.readResponse(rc, trace) //返回response        //response的body是否可写,服务器code101才可写,所以正常这个是false        bodyWritable := resp.bodyIsWritable()        //response.Close设置循环结束,退出协程        if resp.Close || rc.req.Close || resp.StatusCode <= 199 || bodyWritable {                    alive = false        }                  //把response写入通道,在步骤6会读取这个通道        select {        case rc.ch <- responseAndError{res: resp}:        case <-rc.callerGone:            return        }        //循环结束的一些情况        select {        case bodyEOF := <-waitForBodyRead: //读完body也会自动结束                    case <-rc.req.Cancel:        case <-rc.req.Context().Done():        case <-pc.closech:            alive = false            pc.t.CancelRequest(rc.req)        }    }
5.4.1 pc.readResponse 获取response
func (pc *persistConn) readResponse(rc requestAndChan, trace *httptrace.ClientTrace) (resp *Response, err error) {    for{        resp, err = ReadResponse(pc.br, rc.req) //获取response    }}
5.4.2 ReadResponse读取response
func ReadResponse(r *bufio.Reader, req *Request) (*Response, error) {    tp := textproto.NewReader(r) //可以处理HTTP, NNTP, SMTP协议的内容,方便读取    resp := &Response{        Request: req,    }        line, err := tp.ReadLine()//读取第一行,获取协议,状态码    resp.Proto = line[:i]    resp.Status = strings.TrimLeft(line[i+1:], " ")    mimeHeader, err := tp.ReadMIMEHeader()//读取header头    resp.Header = Header(mimeHeader)}
5.5 写协程
func (pc *persistConn) writeLoop() {    for {        select {        case wr := <-pc.writech:            startBytesWritten := pc.nwrite            err := wr.req.Request.write(pc.bw, pc.isProxy, wr.req.extra, pc.waitForContinue(wr.continueCh))                }}

6.使用连接对象*persistConn获取response

func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err error) {    var continueCh chan struct{}    resc := make(chan responseAndError) //response通道    pc.writech <- writeRequest{req, writeErrCh, continueCh}//written by roundTrip; read by writeLoop       pc.reqch <- requestAndChan{ //written by roundTrip; read by readLoop        req:        req.Request,        ch:         resc,        addedGzip:  requestedGzip,        continueCh: continueCh,        callerGone: gone,    }    for { //监听这些通道        testHookWaitResLoop()        select {        case err := <-writeErrCh:                    case <-pc.closech:                    case re := <-resc: //监听 response通道,返回response                     return re.res, nil        }    }}

感谢各位的阅读!关于“Go中http client的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

--结束END--

本文标题: Go中http client的示例分析

本文链接: https://lsjlt.com/news/276098.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Go中http client的示例分析
    这篇文章给大家分享的是有关Go中http client的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。什么是gogo是golang的简称,golang 是Google开发的一种静态强类型、编译型、并发型,...
    99+
    2023-06-15
  • Angular2中http jsonp的示例分析
    这篇文章主要介绍Angular2中http jsonp的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Angular2 Http 1. 使用Http 绝大部分应用程序都会和后...
    99+
    2024-04-02
  • storm-kafka-client使用的示例分析
    storm-kafka-client使用的示例分析,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。package hgs.core.sk;import jav...
    99+
    2023-06-02
  • Node.js中的http请求客户端示例(request client)
    Node.JS有一个request模块,可以很方便的抓取网页内容。最简单的一个示例: var request = require('request'); request('http://www.goo...
    99+
    2022-06-04
    示例 客户端 js
  • php中http请求类的示例分析
    这篇文章将为大家详细讲解有关php中http请求类的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。代码:<php namespace dollar...
    99+
    2024-04-02
  • HTTP状态码的示例分析
    这篇文章将为大家详细讲解有关HTTP状态码的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。HTTP 状态码1、状态码分类  - 1xx:信息,服务器收到...
    99+
    2024-04-02
  • HTTP响应头的示例分析
    这篇文章给大家分享的是有关HTTP响应头的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。HTTP请求头提供了关于请求,响应或者其他的发送实体的信息。HTTP的头信息包括通用头、请求头、响应头和实体头四个部...
    99+
    2023-06-27
  • angularjs中$http提交数据的示例分析
    小编给大家分享一下angularjs中$http提交数据的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!前两天在搞自己的...
    99+
    2024-04-02
  • linux中tcpdump抓取HTTP包的示例分析
    这篇文章将为大家详细讲解有关linux中tcpdump抓取HTTP包的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。tcpdumptcpdump是linux系统自带的抓包工具,主要通过命令行的方式...
    99+
    2023-06-10
  • Tomcat中HTTP请求过程的示例分析
    这篇文章给大家分享的是有关Tomcat中HTTP请求过程的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。初探Tomcat的HTTP请求过程前言:1.作为Java开发人员,大多都对Tomcat不陌生,由Ap...
    99+
    2023-06-02
  • Go中Waitgroup和锁的示例分析
    这篇文章给大家分享的是有关Go中Waitgroup和锁的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。学 Go 的时候知道 Go 语言支持并发,最简单的方法是通过 go 关键字开启 goroutine 即...
    99+
    2023-06-15
  • http前端存储的示例分析
    小编给大家分享一下http前端存储的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!cookie为什么会有cookieht...
    99+
    2024-04-02
  • 前端HTTP协议的示例分析
    这篇文章将为大家详细讲解有关前端HTTP协议的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。实际上前端功能会在实际开发中经常的接触浏览器网络相关的,一共四个部分。1、原因如图,那么为什么要在前端进...
    99+
    2023-06-05
  • http访问解析流程的示例分析
    这篇文章给大家分享的是有关http访问解析流程的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。http访问网址域名解析流程:1、在浏览器中输入www.qq.com域名,操...
    99+
    2024-04-02
  • Vue2.0中http请求以及loading展示的示例分析
    这篇文章主要为大家展示了“Vue2.0中http请求以及loading展示的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Vue2.0中http请求以及...
    99+
    2024-04-02
  • ES6 Fetch API HTTP请求的示例分析
    这篇文章主要为大家展示了“ES6 Fetch API HTTP请求的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“ES6 Fetch API HTTP请...
    99+
    2024-04-02
  • html5中http轮询和Websocket原理的示例分析
    小编给大家分享一下html5中http轮询和Websocket原理的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、H...
    99+
    2024-04-02
  • swoole HTTP服务器中异步MySQL的示例分析
    这篇“swoole HTTP服务器中异步MySQL的示例分析”除了程序员外大部分人都不太理解,今天小编为了让大家更加理解“swoole HTTP服务器中异步MySQL的示例分析”,给大家总结了以下内容,具有一定借鉴价值,内容详细步骤清晰,细...
    99+
    2023-06-14
  • PHP协程中Go+Chan+Defer的示例分析
    这篇文章主要为大家展示了“PHP协程中Go+Chan+Defer的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“PHP协程中Go+Chan+Defer的示例分析”这篇文章吧。Swoole...
    99+
    2023-06-16
  • Go语言中通道channel的示例分析
    这篇文章将为大家详细讲解有关Go语言中通道channel的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、Go语言通道基础概念1.channel产生背景    线程...
    99+
    2023-06-29
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作