Я пытаюсь использовать Pyro для управления ведомой машиной. Я rsync необходимые файлы python, запустить Pyro сервер, выполнить некоторые действия с помощью пульта дистанционного управления, а затем я хочу сказать Pyro сервер, чтобы закрыть.Как я могу выйти из Pyro 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-сервера, но я получаю его все время для «сервера имен». Удар CTRL + C на NameServer имеет 50% -ный шанс вызвать эту ошибку, если я снова запустил сервер имен в течение 30 секунд. У вас было это раньше? –