4

Python の xmlrpclib を使用して、xml-rpc サービスにリクエストを送信しています。

クライアントのタイムアウトを設定する方法はありますか? サーバーが利用できないときにリクエストが永久にハングしないようにする方法はありますか?

でソケットのタイムアウトをグローバルに設定できることはわかっていますsocket.setdefaulttimeout()が、それは好ましくありません。

4

5 に答える 5

12

クリーンなアプローチは、カスタムトランスポートを定義して使用することです。例:!これはpython2.7でのみ機能します!

import xmlrpclib, httplib

class TimeoutTransport(xmlrpclib.Transport):
    timeout = 10.0
    def set_timeout(self, timeout):
        self.timeout = timeout
    def make_connection(self, host):
        h = httplib.HTTPConnection(host, timeout=self.timeout)
        return h

t = TimeoutTransport()
t.set_timeout(20.0)
server = xmlrpclib.Server('http://time.xmlrpc.com/RPC2', transport=t)

ドキュメントにカスタムトランスポートを定義して使用する例がありますが、それは別の目的(タイムアウトを設定するのではなく、プロキシを介したアクセス)で使用していますが、このコードは基本的にその例に触発されています。

于 2010-03-11T15:37:48.640 に答える
8

doh、python2.6 +でこれを機能させるには、次のようにします。

class HTTP_with_timeout(httplib.HTTP):
    def __init__(self, host='', port=None, strict=None, timeout=5.0):
        if port == 0: port = None
        self._setup(self._connection_class(host, port, strict, timeout=timeout))

    def getresponse(self, *args, **kw):
        return self._conn.getresponse(*args, **kw)

class TimeoutTransport(xmlrpclib.Transport):
    timeout = 10.0
    def set_timeout(self, timeout):
        self.timeout = timeout
    def make_connection(self, host):
        h = HTTP_with_timeout(host, timeout=self.timeout)
        return h
于 2011-05-16T08:42:05.427 に答える
5

なぜだめですか:

class TimeoutTransport(xmlrpclib.Transport):

def setTimeout(self, timeout):
    self._timeout = timeout

def make_connection(self, host):
    return httplib.HTTPConnection(host, timeout=self._timeout)

?

結局のところ、HTTP古いHTTPSPython バージョンの互換性クラスに過ぎないようです。

于 2011-06-28T16:40:19.180 に答える
3

Python 2.7 と互換性のある別の実装は次のようになります (Python 2.6 を使用している場合に必要なものを含むコメント付き):

import socket
import xmlrpclib

class TimeoutTransport (xmlrpclib.Transport):
    """
    Custom XML-RPC transport class for HTTP connections, allowing a timeout in
    the base connection.
    """

    def __init__(self, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, use_datetime=0):
        xmlrpclib.Transport.__init__(self, use_datetime)
        self._timeout = timeout

    def make_connection(self, host):
        # If using python 2.6, since that implementation normally returns the 
        # HTTP compatibility class, which doesn't have a timeout feature.
        #import httplib
        #host, extra_headers, x509 = self.get_host_info(host)
        #return httplib.HTTPConnection(host, timeout=self._timeout)

        conn = xmlrpclib.Transport.make_connection(self, host)
        conn.timeout = self._timeout
        return conn

# Example use
t = TimeoutTransport(timeout=10)
server = xmlrpclib.ServerProxy('http://time.xmlrpc.com/RPC2', transport=t)

スーパーメソッドを使用すると、基盤となる 2.7 実装が定義する HTTP/1.1 キープアライブ機能を維持できるようになります。

注意すべきことは、https 接続/アドレスで XML-RPC を使用しようとしている場合は、代わりにxmlrpc.SafeTransport参照をに置き換えxmlrpc.Transport、2.6 実装を使用している場合は を使用することですhttplib.HTTPSConnection

于 2013-06-06T20:19:49.177 に答える