我試圖用Pyro來控制一臺奴隸機器。我rsync必要的python文件,啓動一個Pyro服務器,通過遠程控制執行一些操作,然後我想告訴Pyro服務器關閉。如何通過客戶端請求乾淨地退出Pyro Daemon?
我很難讓Pryo Daemon乾淨地關閉。它掛在Daemon.close()
呼叫中,或者如果我註釋掉該線路,它將在沒有正確關閉其插座的情況下退出,如果我過早重新啓動服務器,則會導致socket.error: [Errno 98] Address already in use
。
它不認爲SO_REUSEADDR是正確的修復方法,因爲不正確的套接字關閉仍會導致套接字在TIME_WAIT狀態下掛起,可能導致某些客戶端遇到問題。我認爲更好的解決方案是說服Pyro Daemon正確關閉它的套接字。
從守護進程本身中調用Daemon.shutdown()是否不正確?
如果我啓動服務器,然後按CTRL-C沒有任何客戶端連接,我沒有任何問題(沒有Address already in use
錯誤)。在大多數情況下(假設客戶端和服務器都是正常的),這似乎是可能的。
實施例:server.py
import Pyro4
class TestAPI:
def __init__(self, daemon):
self.daemon = daemon
def hello(self, msg):
print 'client said {}'.format(msg)
return 'hola'
def shutdown(self):
print 'shutting down...'
self.daemon.shutdown()
if __name__ == '__main__':
daemon = Pyro4.Daemon(port=9999)
tapi = TestAPI(daemon)
uri = daemon.register(tapi, objectId='TestAPI')
daemon.requestLoop()
print 'exited requestLoop'
daemon.close() # this hangs
print 'daemon closed'
實施例:client.py
import Pyro4
if __name__ == '__main__':
uri = 'PYRO:[email protected]:9999'
remote = Pyro4.Proxy(uri)
response = remote.hello('hello')
print 'server said {}'.format(response)
try:
remote.shutdown()
except Pyro4.errors.ConnectionClosedError:
pass
print 'client exiting'
嘿埃裏克。我從來沒有使用Pyro服務器的'Address already in'地址,但是我一直爲'Name Server'服務。如果我在30秒內再次運行名稱服務器,則NameServer上的CTRL + C有50%的機會導致該錯誤。你有過這個嗎? –