0

次のような状況があります。私の Pyro4 プロジェクトには、サーバーとクライアントがあります。サーバーには、同じコールバック オブジェクトで 2 つのコールバックを呼び出す必要があるメソッドが含まれています。したがって、クラスCallbackには と の 2 つのコールバック メソッドがCallback()ありSecondCallback()ます。これらのコールバック メソッドの呼び出しの間には、多少の遅延があります。を呼び出して、私の例でこの遅延をシミュレートしましたtime.sleep

Pyro4 ( Pyro4.config.COMMTIMEOUT) にタイムアウトを設定する必要があります。これがないと、Pyro4 デーモンがrequestLoopメソッドから抜け出せないからです。これは、コールバック メソッドを 1 つだけ呼び出す場合には完全に機能しますが、2 つ目のコールバック メソッドを呼び出す必要がある場合、Pyro4 コールバック デーモンは、最初のコールバック メソッドが呼び出された後 + タイムアウトして接続を閉じます。

タイムアウトをより大きな値に設定しようとしましたが、このタイムアウトは、requestLoopメソッドが loopCondition を処理するまでブロックする時間でもあります。

私の問題を示すスクリプトの例を以下に示します。Pyro4 ネームサーバーを起動した後、サーバーを起動して起動する必要があります:

python -m Pyro4.naming

python test.py -s

その後、新しいコマンド ウィンドウでクライアントを起動します。

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

私の最後の質問は: 2 番目のコールバックが呼び出されたときに COMMTIMEOUT が期限切れになった後、Pyro4 が接続を閉じないようにするにはどうすればよいですか?

この情報がすべて理解できるほど明確であることを願っています。

ご協力ありがとうございました。

4

2 に答える 2

0

正直なところ、あなたの質問は少し奇妙です。

一方では、COMMTIMEOUT を 0.5 秒の (非常に低い) 値に設定しているため、タイムアウトの概念が有効になります。一方、サーバー上の接続を閉じるタイムアウトを取得しないように求めています。何が欲しいの?

しかし、ええ、_pyroReconnect切断されたプロキシを再接続するために使用できます。autoreconnectPyro4 に付属の readmeとサンプルのコードも参照してくださいdisconnects

于 2015-09-10T18:11:14.153 に答える