【问题标题】:Use Python xmlrpclib with unix domain sockets?将 Python xmlrpclib 与 unix 域套接字一起使用?
【发布时间】:2012-07-28 13:45:19
【问题描述】:

我正在尝试与 supervisord 进行交互,我想通过 unix 套接字(它是一个共享托管环境)与它交谈。

到目前为止我尝试过的是:

import xmlrpclib
server = xmlrpclib.ServerProxy('unix:///path/to/supervisor.sock/RPC2')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/xmlrpclib.py", line 1549, in __init__
    raise IOError, "unsupported XML-RPC protocol"
IOError: unsupported XML-RPC protocol

/path/to/supervisor.sock 绝对存在。 supervisord 使用了 'unix:///path/to/supervisor.sock/RPC2' 形式的 URI,这就是我的想法。文档不讨论 unix 套接字:http://docs.python.org/library/xmlrpclib.html

这可能吗?我应该使用其他库吗?

【问题讨论】:

    标签: python xml-rpc xmlrpclib unix-socket


    【解决方案1】:

    xmlrpclib 要求传递的 url 以 httphttps 开头。解决这个问题的方法是定义一个忽略该 url 的自定义传输。下面是一些使用来自主管的传输的代码:

    import supervisor.xmlrpc
    import xmlrpclib
    
    proxy = xmlrpclib.ServerProxy('http://127.0.0.1',
                                   transport=supervisor.xmlrpc.SupervisorTransport(
                                        None, None, serverurl='unix://'+socketpath))
    
    proxy.supervisor.getState()
    

    如果没有用,这里是找到的代码的更新版本here

    class UnixStreamHTTPConnection(httplib.HTTPConnection, object):
        def __init__(self, *args, **kwargs):
            self.socketpath = kwargs.pop('socketpath')
            super(UnixStreamHTTPConnection, self).__init__(*args, **kwargs)
    
        def connect(self):
            self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
            self.sock.connect_ex(self.socketpath)
    
    class UnixStreamTransport(xmlrpclib.Transport, object):
        def __init__(self, *args, **kwargs):
            self.socketpath = kwargs.pop('socketpath')
            super(UnixStreamTransport, self).__init__(*args, **kwargs)
    

    【讨论】:

      【解决方案2】:

      我的python3版本,根据上面的版本准备。

      from http.client import HTTPConnection
      import socket
      from xmlrpc import client
      
      class UnixStreamHTTPConnection(HTTPConnection):
          def connect(self):
              self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
              self.sock.connect(self.host)
      
      class UnixStreamTransport(client.Transport, object):
          def __init__(self, socket_path):
              self.socket_path = socket_path
              super(UnixStreamTransport, self).__init__()
      
          def make_connection(self, host):
              return UnixStreamHTTPConnection(self.socket_path)
      
      proxy = client.ServerProxy('http://localhost', transport=UnixStreamTransport("/var/run/supervisor.sock"))
      
      print(proxy.supervisor.getState())
      

      【讨论】:

        【解决方案3】:

        这是使用 xmlrpclib 与主管对话的更新示例:

        import httplib
        import socket
        import xmlrpclib
        
        class UnixStreamHTTPConnection(httplib.HTTPConnection):
            def connect(self):
                self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
                self.sock.connect(self.host)
        
        class UnixStreamTransport(xmlrpclib.Transport, object):
            def __init__(self, socket_path):
                self.socket_path = socket_path
                super(UnixStreamTransport, self).__init__()
        
            def make_connection(self, host):
                return UnixStreamHTTPConnection(self.socket_path)
        
        
        server = xmlrpclib.Server('http://arg_unused', transport=UnixStreamTransport("/var/run/supervisor.sock"))
        print(server.supervisor.getState())
        

        正如已经提到的,我们必须使用 http:// 或 https:// 指定一个虚拟 url,然后指定一个自定义传输来处理域套接字

        【讨论】:

          【解决方案4】:

          混合上面的答案,这对我有用...

          import httplib
          import socket
          import xmlrpclib
          
          class UnixStreamHTTPConnection(httplib.HTTPConnection, object):
              def __init__(self, *args, **kwargs):
                  self.socketpath = kwargs.pop('socketpath')
                  super(UnixStreamHTTPConnection, self).__init__(*args, **kwargs)
          
              def connect(self):
                  self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
                  self.sock.connect(self.socketpath)
          
          class UnixStreamTransport(xmlrpclib.Transport, object):
              def __init__(self, *args, **kwargs):
                  self.socketpath = kwargs.pop('socketpath')
                  super(UnixStreamTransport, self).__init__(*args, **kwargs)
          
              def make_connection(self, host):
                  return UnixStreamHTTPConnection(host, socketpath=self.socketpath)
          
          server = xmlrpclib.ServerProxy('http://arg_unused', transport=UnixStreamTransport(socketpath="path/to/supervisor.sock"))
          print server.supervisor.getState()
          

          【讨论】:

            猜你喜欢
            • 2011-05-03
            • 1970-01-01
            • 1970-01-01
            • 2014-07-24
            • 2011-02-26
            • 1970-01-01
            • 1970-01-01
            • 2013-01-17
            • 1970-01-01
            相关资源
            最近更新 更多