当前位置: 首页 > 面试题库 >

如何过早关闭/中止Golang http.Client POST

百里杰
2023-03-14
问题内容

我正在使用http.Client长轮询的客户端实现:

resp, err := client.Post(url, "application/json", bytes.NewBuffer(jsonPostBytes))
if err != nil {
    panic(err)
}
defer resp.Body.Close()

var results []*ResponseMessage
err = json.NewDecoder(resp.Body).Decode(&results)  // code blocks here on long-poll

是否有一种标准方法可以从客户端抢占/取消请求?

我想调用resp.Body.Close()会做到这一点,但是我不得不从另一个goroutine调用它,因为通常在读取长轮询的响应时,客户端通常已经被阻塞。

我知道有一种方法可以通过设置超时http.Transport,但是我的应用逻辑需要根据用户操作(而不只是超时)进行取消。


问题答案:

不,client.Post是90%不需要取消请求的用例的便捷包装。

重新实现您的客户端以访问具有CancelRequest()函数的基础传输对象可能就足够了。

只是一个简单的例子:

package main

import (
    "log"
    "net/http"
    "time"
)

func main() {
    req, _ := http.NewRequest("GET", "http://google.com", nil)
    tr := &http.Transport{} // TODO: copy defaults from http.DefaultTransport
    client := &http.Client{Transport: tr}
    c := make(chan error, 1)
    go func() {
        resp, err := client.Do(req)
        // handle response ...
        _ = resp
        c <- err
    }()

    // Simulating user cancel request channel
    user := make(chan struct{}, 0)
    go func() {
        time.Sleep(100 * time.Millisecond)
        user <- struct{}{}
    }()

    for {
        select {
        case <-user:
            log.Println("Cancelling request")
            tr.CancelRequest(req)
        case err := <-c:
            log.Println("Client finished:", err)
            return
        }
    }
}


 类似资料:
  • 问题内容: 我正在尝试进行AJAX调用(通过JQuery),这将启动一个相当长的过程。我希望脚本仅发送一个指示进程已开始的响应,但是JQuery在PHP脚本运行完成之前不会返回响应。 我已经尝试过使用“关闭”标头(如下),以及输出缓冲了。似乎都不起作用。有什么猜想吗?还是我需要在JQuery中做这件事? 问题答案: 以下PHP手册页(包括用户注释)建议了有关如何在不结束PHP脚本的情况下关闭与浏览

  • 我正在使用创建。jar文件。它位于下 然后,创建一个简单的,如下所示: 构建docker映像:

  • 我的nginx配置: 这是nginx或uwsgi的问题,还是两者都有?

  • 请参见下面编辑部分的更新问题 我试图使用GZIPInputStream动态地从Amazon S3解压大型(约300M)GZIPed文件,但它只输出文件的一部分;但是,如果在解压缩之前下载到文件系统,那么GZIPInputStream将解压缩整个文件。 如何让GZIPInputStream解压整个HTTPInputStream,而不仅仅是它的第一部分? 请参见下面编辑部分中的更新 我怀疑是HTTP问

  • 我想做的是:打开大文件的InputStream,读取10MB的块,上传一个块,读取下一个块。 我为这个任务编写了很好的代码,但问题是ContentResolver返回ParcelFileDescriptor。AutoCloseInputStream作为InputStriam。这个实现打破了InputStream的契约,因为它在first.read()之后自动关闭,所以当我尝试读取下一个块时,我得到

  • 问题内容: 我正在使用JAI读取Java中的Tiff文件。使用此代码: 在使用Java 7的一个盒子上工作正常,但在使用Java 8的其他盒子上工作正常,请执行以下操作: 问题答案: 我的理论是,垃圾回收正在启动并完成一些本不该垃圾回收的工作。很奇怪。替换为: 问题似乎消失了。我的猜测是因为不会过早收集,因为它的句柄仍在局部变量范围内。可能还有其他JAI方法也可以做到这一点,只要确保在输入流上保留