首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从rpyc调用xmlrpc方法时xmlrpc.client.Fault

从rpyc调用xmlrpc方法时xmlrpc.client.Fault
EN

Stack Overflow用户
提问于 2019-04-17 13:58:31
回答 2查看 2.6K关注 0票数 0

我正在尝试构建一个有两个进程的系统:一个具有"ping“方法的xmlrpc服务器和一个QCoreApplication中间件。中间件有一个xmlrpc客户端,它连接到xmlrpc服务器。中间件还充当RPyC服务器。我想通过RPyC连接到中间件,并在服务器上调用"ping“方法。

代码语言:javascript
复制
# xmlrpc_server.py
from xmlrpc.server import SimpleXMLRPCServer


class XMLRPCServer(SimpleXMLRPCServer):

    def __init__(self, addr=('localhost', 4444)):
        super(XMLRPCServer, self).__init__(addr)
        self.register_function(self.ping)

    def ping(self):
        return 'pong'


if __name__ == '__main__':
    s = XMLRPCServer()
    s.serve_forever()
代码语言:javascript
复制
# middleware.py
import sys
import xmlrpc.client
import rpyc
import rpyc.utils.server
from PyQt5 import Qt


class MiddleWare(Qt.QCoreApplication):
    def __init__(self, *args, **kwargs):
        super(MiddleWare, self).__init__(*args, **kwargs)
        self.xmlrpc_client = xmlrpc.client.ServerProxy('http://localhost:4444')
        self.rpyc_server = RPyCServer(port=2222)
        self.rpyc_server.start()

    def ping(self):
        return self.xmlrpc_client.ping()


class RPyCService(rpyc.Service):

    def on_connect(self):
        self.exposed_application = Qt.QCoreApplication.instance()


class RPyCServer(Qt.QThread):

    def __init__(self, port=None):
        super(RPyCServer, self).__init__()
        self._server = rpyc.utils.server.ThreadedServer(
                RPyCService,
                port=port,
                protocol_config={
                    'allow_all_attrs': True,
                    'allow_public_attrs': True,
                },
        )
        self.run = self._server.start


if __name__ == '__main__':
    mw = MiddleWare(sys.argv)
    sys.exit(mw.exec_())
代码语言:javascript
复制
$ python3 xmlrpc_server.py &
[1] 5785
$ python3 middleware.py &
[2] 5986
$ python3
Python 3.6.7 (default, Oct 22 2018, 11:32:17) 
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import rpyc
>>> conn = rpyc.connect('localhost', 2222, config={'allow_all_attrs': True})
>>> conn.root.application.ping()
'pong'
>>> conn.root.application.xmlrpc_client.ping()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3/dist-packages/rpyc/core/netref.py", line 199, in __call__
    return syncreq(_self, consts.HANDLE_CALL, args, kwargs)
  File "/usr/lib/python3/dist-packages/rpyc/core/netref.py", line 72, in syncreq
    return conn.sync_request(handler, oid, *args)
  File "/usr/lib/python3/dist-packages/rpyc/core/protocol.py", line 523, in sync_request
    raise obj
rpyc.core.vinegar/xmlrpc.client.Fault: 

========= Remote Traceback (1) =========
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/rpyc/core/protocol.py", line 347, in _dispatch_request
    res = self._HANDLERS[handler](self, *args)
  File "/usr/lib/python3/dist-packages/rpyc/core/protocol.py", line 624, in _handle_call
    return self._local_objects[oid](*args, **dict(kwargs))
  File "/usr/lib/python3.6/xmlrpc/client.py", line 1112, in __call__
    return self.__send(self.__name, args)
  File "/usr/lib/python3.6/xmlrpc/client.py", line 1452, in __request
    verbose=self.__verbose
  File "/usr/lib/python3.6/xmlrpc/client.py", line 1154, in request
    return self.single_request(host, handler, request_body, verbose)
  File "/usr/lib/python3.6/xmlrpc/client.py", line 1170, in single_request
    return self.parse_response(resp)
  File "/usr/lib/python3.6/xmlrpc/client.py", line 1342, in parse_response
    return u.close()
  File "/usr/lib/python3.6/xmlrpc/client.py", line 656, in close
    raise Fault(**self._stack[0])
xmlrpc.client.Fault: <Fault 1: '<class \'Exception\'>:method "exposed_ping" is not supported'>

>>> 

在调用conn.root.application.ping()和直接调用conn.root.application.xmlrpc_client.ping()时,我希望从调用中获得'pong‘值,而在第二种情况下则会显示错误。为什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-04-18 08:04:54

我能够通过编辑protocol_config获得所需的结果,添加

代码语言:javascript
复制
'exposed_prefix': ''
代码语言:javascript
复制
# middleware.py
#   ...

class RPyCServer(Qt.QThread):

    def __init__(self, port=None):
        super(RPyCServer, self).__init__()
        self._server = rpyc.utils.server.ThreadedServer(
                RPyCService,
                port=port,
                protocol_config={
                    'allow_all_attrs': True,
                    'exposed_prefix': '',
                },
        )
        self.run = self._server.start

#   ...
代码语言:javascript
复制
$ python3
Python 3.6.7 (default, Oct 22 2018, 11:32:17) 
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import rpyc
>>> conn = rpyc.connect('localhost', 2222, config={'allow_all_attrs': True, 'exposed_prefix': ''})
>>> conn.root.application.ping()
'pong'
>>> conn.root.application.xmlrpc_client.ping()
'pong'
>>>
票数 0
EN

Stack Overflow用户

发布于 2019-04-18 07:58:53

  • 正如我对rpyc==3.4.4所看到的,在注册函数时,您必须向它传递一个名称:
代码语言:javascript
复制
from xmlrpc.server import SimpleXMLRPCServer


class XMLRPCServer(SimpleXMLRPCServer):
    def __init__(self, addr=("localhost", 4444)):
        super(XMLRPCServer, self).__init__(addr)
        self.register_function(self.ping, "exposed_ping") # <---

    def ping(self):
        return "pong"


if __name__ == "__main__":
    s = XMLRPCServer()
    s.serve_forever()
  • 但是,在rpyc==4.0.2中,没有必要这样做,但您可以使用on_connect的第二个参数:
代码语言:javascript
复制
# ...
class RPyCService(rpyc.Service):
    def on_connect(self, conn):
        self.exposed_application = Qt.QCoreApplication.instance()
# ...
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55729278

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档