【问题标题】:How do I prevent Pyro4 from closing the connection after COMMTIMEOUT如何防止 Pyro4 在 COMMTIMEOUT 后关闭连接
【发布时间】:2015-09-11 02:11:14
【问题描述】:

我有以下情况;我的 Pyro4 项目有一个服务器和一个客户端。服务器包含一个需要在同一个回调对象上调用 2 个回调的方法。所以Callback类有两个回调方法:Callback()SecondCallback()。这些回调方法的调用之间存在一些延迟。在我的示例中,我通过调用 time.sleep 模拟了这种延迟。

我需要在 Pyro4 (Pyro4.config.COMMTIMEOUT) 上设置一个超时,因为没有这个,Pyro4 守护进程将永远不会脱离 requestLoop 方法。这在仅调用一个回调方法时非常有效,但是当您必须调用第二个回调方法时,Pyro4 回调守护程序会在调用第一个回调方法 + 超时后关闭连接。

我尝试将超时设置为更大的值,但此超时也是 requestLoop 方法阻塞直到它处理 loopCondition 的时间。

下面包含一个演示我的问题的示例脚本。您需要在启动 Pyro4 名称服务器后通过启动服务器来启动它:

python -m Pyro4.naming

python test.py -s

然后在新的 cmd 窗口中启动客户端:

python test.py

Test.py

import Pyro4, time
from argparse import ArgumentParser

ip = "127.0.0.1"

class Server:

    def __init__(self):
        pass

    def ActionOne(self):
        return "Foo"

    def ActionTwo(self):
        return "Bar"

    @Pyro4.oneway
    def ActionThree(self, callback):
        time.sleep(4)
        callback.Callback()
        time.sleep(3)
        callback.SecondCallback()

class Callback:

    def __init__(self):
        self.Executed = False
        pass

    def Callback(self):
        print "FooBar"

    def SecondCallback(self):
        print "raBooF"
        self.Executed = True

def loopWhile(condition):
    while condition:
        time.sleep(.1)


if __name__ == "__main__":
    parser = ArgumentParser()
    parser.add_argument("--server", "-s", action="store_true")

    args = parser.parse_args()
    if(args.server):
        print "Server"

        daemon = Pyro4.core.Daemon(host=ip)
        uri = daemon.register(Server())

        ns = Pyro4.naming.locateNS(host=ip)
        ns.register("server", uri)

        daemon.requestLoop()

        pass
    else:
        print "Client"
        Pyro4.config.COMMTIMEOUT = .5

        ns = Pyro4.naming.locateNS(host=ip)
        serverUri = ns.lookup("server")
        proxy = Pyro4.core.Proxy(serverUri)

        print proxy.ActionOne()
        print proxy.ActionTwo()

        daemon = Pyro4.core.Daemon(host=ip)
        callback = Callback()
        daemon.register(callback)

        proxy.ActionThree(callback)
        daemon.requestLoop(lambda: not callback.Executed)
        print "FINISHED"

这个脚本的结果:

Server:

Server
Exception in thread Thread-17:
Traceback (most recent call last):
  File "C:\Program Files (x86)\IronPython 2.7\Lib\threading.py", line 552, in _T
hread__bootstrap_inner
    self.run()
  File "C:\Program Files (x86)\IronPython 2.7\Lib\threading.py", line 505, in ru
n
    self.__target(*self.__args, **self.__kwargs)
  File "test.py", line 22, in ActionThree
    callback.SecondCallback()
  File "C:\Program Files (x86)\IronPython 2.7\lib\site-packages\Pyro4\core.py",
line 171, in __call__
    return self.__send(self.__name, args, kwargs)
  File "C:\Program Files (x86)\IronPython 2.7\lib\site-packages\Pyro4\core.py",
line 410, in _pyroInvoke
    msg = message.Message.recv(self._pyroConnection, [message.MSG_RESULT], hmac_
key=self._pyroHmacKey)
  File "C:\Program Files (x86)\IronPython 2.7\lib\site-packages\Pyro4\message.py
", line 168, in recv
    msg = cls.from_header(connection.recv(cls.header_size))
  File "C:\Program Files (x86)\IronPython 2.7\lib\site-packages\Pyro4\socketutil
.py", line 448, in recv
    return receiveData(self.sock, size)
  File "C:\Program Files (x86)\IronPython 2.7\lib\site-packages\Pyro4\socketutil
.py", line 190, in receiveData
    raise ConnectionClosedError("receiving: connection lost: " + str(x))
ConnectionClosedError: receiving: connection lost: [Errno 10022] A request to se
nd or receive data was disallowed because the socket is not connected and (when
sending on a datagram socket using a sendto call) no address was supplied

Client:

Client
Foo
Bar
FooBar

我的最后一个问题是:当调用第二个回调时,如何防止 Pyro4 在 COMMTIMEOUT 过期后关闭连接?

我希望所有这些信息都足够清晰,可以理解。

感谢您的帮助。

【问题讨论】:

    标签: python asynccallback pyro


    【解决方案1】:

    供将来参考:

    我能够通过调用重新启动与回调的连接:

    callback._pyroReconnect()

    就在调用第二个回调方法之前

    【讨论】:

      【解决方案2】:

      说实话,你的问题有点奇怪。

      一方面,您将 COMMTIMEOUT 配置为 0.5 秒的(非常低的)值,从而启用超时概念。另一方面,您要求不要超时关闭服务器上的连接。你想要什么?

      但是,您可以使用_pyroReconnect 重新连接已断开连接的代理。另请参阅 Pyro4 附带的 autoreconnectdisconnects 示例的自述文件和代码。

      【讨论】:

      • 这个超时在客户端,意味着它将等待 500 毫秒的响应。在我的情况下,我使用回调,它充当服务器,因此我觉得与回调的连接关闭有点奇怪,但与服务器上的代理的连接却没有。
      • 您的客户端代码将完全控制权转移到 daemon.requestLoop 方法,因此不再对客户端代理执行任何操作。所以没有什么可以注册任何超时。
      猜你喜欢
      • 2017-04-05
      • 2018-02-06
      • 1970-01-01
      • 2016-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-21
      • 1970-01-01
      相关资源
      最近更新 更多