2013-03-01 52 views
5

我已經寫了一個非常簡單的客戶端,用於使用python優秀的請求庫的其餘API。一切工作都很好util我通過負載平衡器運行客戶端,這會正確地檢測閒置的TCP連接並殺死它們。我希望我的客戶端使用一些不同的tcp keep alive選項,而不是我的平臺(linux)上的默認選項。但我沒有看到任何簡單的方法來告訴套接字庫,我想爲新的套接字選擇一些默認選項。是否有可能重寫請求中的默認套接字選項?

當直接使用socket.create_connection時,這對於裝飾器來說很容易做到,但我不知道如何在實際調用被隱藏在某個第三方庫中時使該裝飾調用可用,如同與請求。

在此先感謝

+0

讓我猜:azure? – Dacav 2015-10-30 11:21:43

回答

3

requests使用urllib3,它使用標準庫的http.client(或httplib,爲2.X),要求socket.create_connection,所有,而不會有任何事物鉤。

所以,你要麼必須分叉那些庫中的一個,要麼在運行中monkeatch。

做最簡單的地方大概是http.client.connect,因爲這是圍繞socket.create_connection一個簡單的包裝,可以很容易地換出:

orig_connect = http.client.HTTPConnection.connect 
def monkey_connect(self): 
    orig_connect(self) 
    self.sock.setsockopt(…) 
http.client.HTTPConnection.connect = monkey_connect 

如果你在2.x中,它可能是那樣簡單只是使用httplib而不是上面的http.client,但您可能想驗證一下。

+0

真棒解決方案,我沒有意識到模塊的範圍工作方式。 – 2013-03-01 00:47:11

+1

自從'urllib3' 1.8.3開始,現在可以通過'HTTPConnection.socket_options'或'HTTPConnection.default_socket_options'完成。 – univerio 2016-02-08 20:04:41

5

較新版本的urllib3(自1.8.3,發佈於2014-06-23)支持設置套接字選項。

您可以通過創建自定義適配器設置從requests這些選項(自2.4.0發佈2014年8月29日):

class HTTPAdapterWithSocketOptions(requests.adapters.HTTPAdapter): 
    def __init__(self, *args, **kwargs): 
     self.socket_options = kwargs.pop("socket_options", None) 
     super(HTTPAdapterWithSocketOptions, self).__init__(*args, **kwargs) 

    def init_poolmanager(self, *args, **kwargs): 
     if self.socket_options is not None: 
      kwargs["socket_options"] = self.socket_options 
     super(HTTPAdapterWithSocketOptions, self).init_poolmanager(*args, **kwargs) 

然後你可以將此適配器安裝到需要自定義套接字會議選項(例如設置SO_KEEPALIVE):

adapter = HTTPAdapterWithSocketOptions(socket_options=[(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)]) 
s = requests.session() 
s.mount("http://", adapter) 
s.mount("https://", adapter) 
+0

應該是requests.Session()? – 2016-10-19 14:18:26

+0

@JasonHeiss這些是可以互換的。 – univerio 2016-10-19 19:46:10

相關問題