【问题标题】:Returning remote object in rpyc在 rpyc 中返回远程对象
【发布时间】:2012-02-03 06:35:53
【问题描述】:

我有一个像下面这样的远程服务器,它已经有一个初始化的类,我已经将协议配置设置为允许公共属性 True。

import rpyc

class SharedClass(object):
    def __init__(self,string):
        print string

    def action(self):
        print 'i am doing something'

s=SharedClass('hi')

class MyService(rpyc.Service):
    def on_connect(self):
        pass

    def on_disconnect(self):
        pass

    def exposed_get_shared(self):
        return s

if __name__=='__main__:
    from rpyc.utils.server import ThreadedServer
    t=ThreadedServer(MyService,port=18861,protocol_config={"allow_public_attrs":True})
    t.start()

在客户端,如果我尝试直接连接它正在工作,而 当我尝试在函数内部建立连接并返回对象时 我收到一个错误

**客户端**

**直接连接**

>>>Python 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] on win32
>>>Type "help", "copyright", "credits" or "license" for more information.
>>>conn=rpyc.connect('localhost',18861)
>>>share=getattr(conn.root,'get_shared')
>>>share
<bound method MyService.exposed_get_shared of <__main__.MyService
object at 0x011BA698>>
>>>share=getattr(conn.root,'get_shared')()
>>>share
<__main__.SharedClass object at 0x00B6ED30>
>>>share.action()
i am doing something

如果我尝试在函数中执行此操作,则会出现错误;(

>>>def returnObject(objName, host, port):
...    conn = rpyc.connect(host, port)
...    print conn
...    attr = getattr(conn.root, 'get_' + objName)()
...    print attr
...    return attr
>>>share=returnObject('shared','localhost',18861)
<rpyc.core.protocol.Connection 'conn2' object at 0x0108AAD0>
<__main__.SharedClass object at 0x00B6ED30>
>>>share
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "C:\Python27\lib\site-packages\rpyc\core\netref.py", line 168,
in __repr__
   return syncreq(self, consts.HANDLE_REPR)
 File "C:\Python27\lib\site-packages\rpyc\core\netref.py", line 69,
in syncreq
   return conn().sync_request(handler, oid, *args)
AttributeError: 'NoneType' object has no attribute 'sync_request'

我的目的是在服务器中初始化一个对象并让许多客户端访问它。初始化的类是线程安全的,因此多个客户端可以使用它。

我意识到我在这样做时遗漏了一些东西。

--

阿迪提亚

【问题讨论】:

    标签: python rpyc


    【解决方案1】:

    虽然我对 rpyc 没有真正的经验,但从您的示例看来,唯一真正的区别是在执行 returnObject 函数时不保留“conn”引用,所以我猜这种情况与垃圾收集有关由“conn”引用。对 returnObject 函数稍作修改,使 'conn' 返回并保留在函数之外,该示例似乎可以执行。

    >>> import rpyc
    >>> def returnObject(objName, host, port):
    ...     conn = rpyc.connect(host, port)
    ...     print conn
    ...     attr = getattr(conn.root, 'get_' + objName)()
    ...     print attr
    ...     return conn, attr
    ... 
    >>> conn, share = returnObject('shared', 'localhost', 18861)
    <rpyc.core.protocol.Connection 'conn1' object at 0x10b0676d0>
    <__main__.SharedClass object at 0x1091ff790>
    >>> share
    <__main__.SharedClass object at 0x1091ff790>
    >>> share.action()
    

    由于我参与了另一个 python 远程对象解决方案 Versile Python 的开发,这里只是为了好玩,这里是使用该解决方案的替代实现(需要 VPy 开发版本 0.7.2,下一个版本将有一些冲突的 API 更改)。提供 SharedClass 访问的远程服务:

    from versile.quick import *
    from versile.vse.native.python import VPythonObject
    VSEResolver.add_imports()
    
    class SharedClass(object):
        def action(self):
            return u'I am doing something'
    
    shared = SharedClass()
    
    class Gateway(VExternal):
        @publish(show=True, ctx=False)
        def get_shared(self):
            return VPythonObject(shared)
    
    service = VTPService(lambda: Gateway(), auth=None)
    service.start()
    

    访问服务的客户端代码:

    >>> from versile.quick import *
    >>> VSEResolver.add_imports()
    >>> gw = VUrl.resolve('vtp://localhost/')
    >>> shared = gw.get_shared()
    >>> shared._v_activate() # required for activating as remote-python proxy
    >>> shared.action()
    u'I am doing something'
    >>> gw._v_link.shutdown()
    

    【讨论】:

    • 如果我返回 conn 和 attr,我的代码正在运行。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-30
    • 2011-07-13
    相关资源
    最近更新 更多