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

取消HTTP请求时关闭所有goroutines

东方辉
2023-03-14
问题内容

我正在制作网络爬虫。我将网址传递给搜寻器函数,并对其进行解析以获取锚标记中的所有链接,然后为所有这些网址使用相同的搜寻器函数,并对每个网址使用单独的goroutine。
但是,如果在我收到响应之前发送请求并取消它,则该特定请求的所有程序仍在运行。
现在我想要的是,当我取消请求时,由于该请求而被调用的所有goroutine都会停止。
请指导。
以下是我的 搜寻器 功能代码。

func crawler(c echo.Context, urlRec string, feed chan string, urlList *[]string, wg *sync.WaitGroup) {
    defer wg.Done()
    URL, _ := url.Parse(urlRec)
    response, err := http.Get(urlRec)
    if err != nil {
        log.Print(err)
        return
    }

    body := response.Body
    defer body.Close()

    tokenizer := html.NewTokenizer(body)
    flag := true
    for flag {
        tokenType := tokenizer.Next()
        switch {
        case tokenType == html.ErrorToken:
            flag = false
            break
        case tokenType == html.StartTagToken:
            token := tokenizer.Token()

            // Check if the token is an <a> tag
            isAnchor := token.Data == "a"
            if !isAnchor {
                continue
            }

            ok, urlHref := getReference(token)
            if !ok {
                continue
            }

            // Make sure the url begines in http**
            hasProto := strings.Index(urlHref, "http") == 0
            if hasProto {
                if !urlInURLList(urlHref, urlList) {
                    if strings.Contains(urlHref, URL.Host) {
                        *urlList = append(*urlList, urlHref)
                        // fmt.Println(urlHref)
                        // c.String(http.StatusOK, urlHref+"\n")Documents
                        if !checkExt(filepath.Ext(urlHref)) {
                            wg.Add(1)
                            go crawler(c, urlHref, feed, urlList, wg)
                        }
                    }
                }
            }
        }
    }
}

以下是我的POST请求处理程序

func scrapePOST(c echo.Context) error {
    var urlList []string
    urlSession := urlFound{}
    var wg sync.WaitGroup
    urlParam := c.FormValue("url")
    feed := make(chan string, 1000)
    wg.Add(1)
    go crawler(c, urlParam, feed, &urlList, &wg)
    wg.Wait()
    var count = 0
    for _, url := range urlList {
        if filepath.Ext(url) == ".jpg" || filepath.Ext(url) == ".jpeg" || filepath.Ext(url) == ".png" {
            urlSession.Images = append(urlSession.Images, url)
        } else if filepath.Ext(url) == ".doc" || filepath.Ext(url) == ".docx" || filepath.Ext(url) == ".pdf" || filepath.Ext(url) == ".ppt" {
            urlSession.Documents = append(urlSession.Documents, url)
        } else {
            urlSession.Links = append(urlSession.Links, url)
        }
        count = count + 1
    }
    urlSession.Count = count
    // jsonResp, _ := json.Marshal(urlSession)
    // fmt.Print(urlSession)
    return c.JSON(http.StatusOK, urlSession)
}

问题答案:

回显上下文公开了HTTP请求,该请求已具有已绑定到服务器请求的上下文。只需获取该上下文,并检查其是否取消,和/或将其传递给采用上下文的方法。

ctx := c.Request().Context()
select {
case <-ctx.Done():
    return ctx.Err()
default:
    // Continue handling the request
}

// and pass along to the db or whatever else:
rows, err := db.QueryContext(ctx, ...)

如果客户端中止连接,则请求范围的上下文将自动取消。

如果您想添加自己的取消条件(超时或其他条件),也可以这样做:

req := c.Request()
ctx, cancel := context.WithCancel(req.Context())
req.WithContext(ctx)
defer cancel()
// do stuff, which may conditionally call cancel() to cancel the context early


 类似资料:
  • 目前,我正在使用mrecestQueue.cancelAll(getActive())在一个片段中的on Stop方法,但显然,当我将手机从横向移动到纵向时,它仍然返回请求中的数据,但会导致崩溃,因为持有人数据泄露已经存在了。有什么如何正确处理的示例代码吗?

  • 问题内容: 我想知道,您如何关闭与请求(python-requests.org)的连接? 有了它,但我要如何做请求相同的? 码: 问题答案: 正如这里所讨论的,实际上没有HTTP连接之类的东西,而httplib所指的HTTPConnection实际上是底层的TCP连接,它根本不了解您的请求。索取摘要,您将永远看不到它。 实际上,最新版本的Requests确实使TCP连接保持活动状态。.如果您确实希

  • 如何取消/中止angular 4中所有挂起的HTTP请求。 有一个取消HTTP请求的方法,但是如何一次取消所有挂起的请求。 尤其是在改变路线的时候。 我做了一件事 但是如何在全球范围内实现这一点 有什么想法吗?

  • 问题内容: 有一个新的API用于从JavaScript发出请求:fetch()。是否有任何内置的机制可以在飞行中取消这些请求? 问题答案: 现在支持截至2017年9月20日的参数,但目前 并非所有浏览器都支持此参数 。 2020更新: 大多数主流浏览器(Edge,Firefox,Chrome,Safari,Opera和其他一些浏览器)都支持该功能,该功能已成为DOM生活标准的一部分。(截至2020

  • 问题内容: 问题是,在很长的过程中,无论当前是否已连接客户端浏览器,PHP脚本都会继续执行。如果客户端终止了对脚本的Ajax调用,那么脚本是否也可能在服务器上终止? 问题答案: 正如@metadings指出的那样,php确实具有一个函数来检查连接中止,该连接名为connection_aborted()。如果连接终止,它将返回1,否则返回0。 在漫长的服务器端过程中,用户可能需要了解客户端是否与服务

  • 我使用youtube API制作了一个应用程序。首先,我使用< code > retrieve 加载视频列表,然后我继续使用< code > retrieve 加载列表中视频的所有信息。 由于<code>列表视图<code>支持刷新和加载更多,我需要<code>取消<code>所有调用请求。 我知道调用了<code>cancel()cancel()。 还有更好的解决方案吗?