将 Python xmlrpclib 与 unix 域套接字一起使用?
Posted
技术标签:
【中文标题】将 Python xmlrpclib 与 unix 域套接字一起使用?【英文标题】:Use Python xmlrpclib with unix domain sockets? 【发布时间】: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。
这可能吗?我应该使用其他库吗?
【问题讨论】:
【参考方案1】:xmlrpclib
要求传递的 url 以 http
或 https
开头。解决这个问题的方法是定义一个忽略该 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()
【讨论】:
以上是关于将 Python xmlrpclib 与 unix 域套接字一起使用?的主要内容,如果未能解决你的问题,请参考以下文章
7.python xmlrpclib及allownone作用
如何在 Python 中对 PDF 文件进行 base64 编码
Elastic Beanstalk 上的 Celery + Django 导致错误:<class 'xmlrpclib.Fault'>, <Fault 6: 'SHUTDOWN_ST