Próbuję użyć Pyro do sterowania maszyną podrzędną. Zsynchronizuję niezbędne pliki Pythona, uruchomę serwer Pyro, wykonam niektóre czynności za pomocą zdalnego sterowania, a następnie chcę, aby serwer Pyro został zamknięty.Jak mogę całkowicie zamknąć demona Pyro na żądanie klienta?
Mam problem z wyjęciem demona Pryo w czysty sposób. Zawiesza się ona w wywołaniu Daemon.close()
lub jeśli skomentuję, że linia ta jest zamykana bez wyłączania jego gniazda poprawnie, powodując socket.error: [Errno 98] Address already in use
, jeśli zbyt szybko zrestartuję serwer.
Nie wydaje się, że SO_REUSEADDR jest poprawną instalacją, ponieważ nieczytelne zamknięcie gniazda nadal powoduje, że gniazdo wisi w stanie TIME_WAIT, potencjalnie powodując problemy z niektórymi klientami. Myślę, że lepszym rozwiązaniem jest przekonanie Pyro Daemona do właściwego zamknięcia gniazda.
Czy niewłaściwe jest wywoływanie Daemon.shutdown() z poziomu samego demona?
Jeśli uruchomię serwer, a następnie naciśnij CTRL-C bez podłączonych klientów, nie mam żadnych problemów (nie ma błędów Address already in use
). To sprawia, że czyste wyłączanie wydaje się możliwe, przez większość czasu (zakładając, że jest to normalny klient i serwer).
przykład: 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'
przykład: 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'
Hej Eric. Nigdy nie miałem "Adresu już w użyciu" dla serwera Pyro, ale dostaję go cały czas na "Serwer Nazw". Naciśnięcie CTRL + C na NameServer ma 50% szans na spowodowanie tego błędu, jeśli ponownie uruchomię serwer nazw w ciągu 30 sekund. Czy miałeś to już wcześniej? –