如何使用 PycURL 保持非活动连接打开?

How to keep an inactive connection open with PycURL?

更好地解释问题的伪代码:

#!/usr/bin/env python2.7
import pycurl, threading

def threaded_work():
    conn = pycurl.Curl()
    conn.setopt(pycurl.TIMEOUT, 10)

    # Make a request to host #1 just to open the connection to it.
    conn.setopt(pycurl.URL, 'https://host1.example.com/')
    conn.perform_rs()

    while not condition_that_may_take_very_long:
        conn.setopt(pycurl.URL, 'https://host2.example.com/')
        print 'Response from host #2: ' + conn.perform_rs()

    # Now, after what may be a very long time, we must request host #1 again with a (hopefully) already established connection.
    conn.setopt(pycurl.URL, 'https://host1.example.com/')
    print 'Response from host #1, hopefully with an already established connection from above: ' + conn.perform_rs()
    conn.close()

for _ in xrange(30):
    # Multiple threads must work with host #1 and host #2 individually.
    threading.Thread(target = threaded_work).start()

为了简洁起见,我省略了额外的、不必要的细节,以便突出主要问题。

如您所见,我有多个线程必须与两个不同的主机(主机 #1 和主机 #2)一起工作。大多数情况下,线程将与主机 #2 一起工作,直到满足特定条件。该条件可能需要数小时甚至更长时间才能满足,并且会在不同线程的不同时间得到满足。一旦满足条件(示例中的 condition_that_may_take_very_long),我希望尽快使用我在 threaded_work 方法开始时建立的连接请求主机 #1。有没有什么有效的方法可以有效地完成这个任务(也接受使用两个 PycURL 句柄的建议)?

Pycurl 使用 libcurl。 libcurl 在使用后默认保持连接处于活动状态,因此只要您保持句柄处于活动状态并将其用于后续传输,它就会保持连接处于活动状态并准备好重新使用。

然而,由于现代网络和网络设备(NAT、防火墙、网络服务器),没有流量的连接通常很快就会被关闭,所以有一个空闲连接并期望它在 "hours" 后实际工作,是一个非常渺茫的机会和罕见的事件。通常,libcurl 然后会发现连接已同时被终止,并创建一个新连接以供下次使用。

此外,根据我上面的描述,自 libcurl 7.65.0 以来,它现在默认不再重用早于 118 秒 的连接。可使用 CURLOPT_MAXAGE_CONN 选项更改。原因是它们几乎从不工作,因此通过避免将它们留在身边、检测到它们已死并重新发出请求,这是一种优化。