PyRO 4 - поиск завершается неудачно, когда я пытаюсь найти зарегистрированный объект

Я борюсь с этой проблемой около недели и больше не знаю, где искать решение.

Как видно из заголовка, как только я успешно регистрирую пирообъект, я пытаюсь найти его на NS, чтобы работать с ним, но поиск не удается.

Я публикую упрощенную версию своего кода, чтобы прояснить ситуацию:

Сервер - это класс, в котором запускается PyRO NS:

import threading, socket, sys
import Pyro4


class Server():

    def __init__(self):
        self.start_ns_loop()

    def start_ns(self):

        print("Starting the Name Server...")

        try:

            Pyro4.naming.startNSloop()

        except socket.error:

            print("Name Server already running.")
            sys.exit(0)

    def start_ns_loop(self):

        ns_thread = threading.Thread(target=self.start_ns, args=[])
        ns_thread.daemon = True
        ns_thread.start()

Класс TextAnalyzer - это класс, который я использую для составления статистики о файле:

    import nltk, argparse, Pyro4, socket
    class TextAnalyzer():


    def __init__(self):
        #init function in which I do all my things...

    '''after the init, I've some methods. I don't list them
    because they are not important in this discussion'''

    def get_ip_addr(self):

        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(("8.8.8.8", 80))
        ns_ip = str(s.getsockname()[0])
        s.close()

        return ns_ip


def main():

    global nsip, PYRO_OBJ_NAME
    text_analyzer_name = "Text_Analyzer_"

    # Parser configuration for the input values
    parser = argparse.ArgumentParser(description="Values: ")
    parser.add_argument("-id", help="Sets the text analyzer ip.")
    parser.add_argument("-nsip", help="Sets the Name Server ip.")
    args = parser.parse_args()

    if args.id is not None:
        identifier = str(args.id)
    else:
        identifier = ""

    if args.nsip is not None:
        name_server_ip = str(args.nsip)
    else:
        name_server_ip = ""

    a = TextAnalyzer()

    try:

        if name_server_ip != "":
            nsip = Pyro4.naming.locateNS(name_server_ip)
        else:
            nsip = Pyro4.naming.locateNS()

        PYRO_OBJ_NAME = text_analyzer_name + str(identifier)
        print("PyRO Object name: " + PYRO_OBJ_NAME)
        daemon = Pyro4.Daemon(a.get_ip_addr())

        uri_text_analyzer = daemon.register(a)
        nsip.register(PYRO_OBJ_NAME, uri_text_analyzer, safe=True)

        print("URI " + PYRO_OBJ_NAME + ": " + str(uri_text_analyzer))

        daemon.requestLoop()

    except Pyro4.naming.NamingError as e:

        print(str(e))

if __name__ == "__main__":

    main()

Класс соединения предоставляет все методы, полезные для поиска объекта в соединениях NS, sftp и ssh, находит PID запущенных объектов и т. Д...

import Pyro4, paramiko, socket, time
from PyQt4 import QtCore, QtGui


class Connection(QtGui.QMainWindow):

def __init__(self):

    super(Connection, self).__init__()

    self.text_analyzer_name = "Text_Analyzer_"
    self.identifier = None
    self.address = None
    self.password = None
    self.object_pid = None
    self.authentication_ok = False

def get_ip_addr(self):

    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.connect(("8.8.8.8", 80))
    ns_ip = str(s.getsockname()[0])
    s.close()
    print(ns_ip)
    return ns_ip

# This method finds the object on the NS
def find_obj(self, identifier, a, p):

    self.identifier = identifier
    self.address = a
    self.password = p

    self.open_server_connection()

    time.sleep(5)

    if self.authentication_ok is True:

        try:
            ns = Pyro4.naming.locateNS()
            print("Return del locateNS(): " + str(ns))
            uri_text_analyzer = ns.lookup(self.text_analyzer_name + str(self.identifier))
            self.text_analyzer = Pyro4.Proxy(uri_text_analyzer)
            return True

        except Pyro4.errors.NamingError as e:
            print(str(e))
            self.ssh_connection_close_and_cleanup()
            return False

def open_server_connection(self):

    print("Object ID: " + str(self.identifier))

    ssh_connection = paramiko.SSHClient()

    ssh_connection.load_system_host_keys()

    ssh_connection.set_missing_host_key_policy(paramiko.AutoAddPolicy)

    try:
        if str(self.address).__contains__('@'):
            (username, hostname) = self.address.split('@')
            print("User: " + username + ", Host: " + hostname)
            print("Tento la connessione.")
            ssh_connection.connect(str(hostname), username=username, password=str(self.password), timeout=5, allow_agent=False)

        else:
            ssh_connection.connect(str(self.address), password=str(self.password), timeout=5, allow_agent=False)

        self.authentication_ok = True

        ns_ip = self.get_ip_addr()
        sftp_connection = ssh_connection.open_sftp()
        print("Sftp connection open.")
        print("Transferring " + self.text_analyzer_name + str(self.identifier) + "...")
        sftp_connection.put("text_analyzer.py", "./text_analyzer.py")
        print("Transferring Pyro4...")
        sftp_connection.put("Pyro4.zip", "./Pyro4.zip")
        print("Unpacking...")
        stdin, stdout, stderr = ssh_connection.exec_command("tar -xzvf Pyro4.zip")
        time.sleep(3)
        print("Executing " + self.text_analyzer_name + str(self.identifier) + ":")
        stdin, stdout, stderr = ssh_connection.exec_command("echo $$; exec python3 text_analyzer.py -id {} -nsip {}".format(self.identifier, ns_ip))

        # Object PID saving
        self.object_pid = int(stdout.readline())
        print("PID del " + self.text_analyzer_name + str(self.identifier) + ": " + str(self.object_pid))
        # Connections close
        ssh_connection.close()
        sftp_connection.close()

    except (paramiko.AuthenticationException, socket.error) as e:
        self.authentication_ok = False
        ssh_connection.close()
        print("Connection failed, error: " + str(e))

def ssh_connection_close_and_cleanup(self):

    ssh_connection = paramiko.SSHClient()

    ssh_connection.load_system_host_keys()

    ssh_connection.set_missing_host_key_policy(paramiko.AutoAddPolicy)

    try:
        if str(self.address).__contains__('@'):
            (username, hostname) = self.address.split('@')
            ssh_connection.connect(str(hostname), username=username, password=str(self.password), timeout=5, allow_agent=False)
        else:
            ssh_connection.connect(str(self.address), password=str(self.password), timeout=5, allow_agent=False)

        self.host = hostname
        print("Killing PID: " + str(self.object_pid))
        ssh_connection.exec_command("/bin/kill -KILL {}".format(self.object_pid))
        ssh_connection.exec_command("rm -r Pyro4")
        ssh_connection.exec_command("rm -r Pyro4.zip")
        ssh_connection.exec_command("rm text_analyzer.py")
        time.sleep(5)

        ssh_connection.close()

    except(paramiko.AuthenticationException, socket.error) as e:
        ssh_connection.close()
        print("Connection failed")
        print(str(e))

Итак, в основном, это то, что я делаю.

Проблема заключается в том, что поиск завершается неудачно при попытке найти удаленный объект в NS внутри метода find_obj() (содержится в классе Connection), но я точно знаю, что удаленный объект был успешно зарегистрирован.

Данная ошибка называется "неизвестное имя" из Pyro4.errors.NamingError.

Я действительно понятия не имею, почему это не работает...

Дальнейшие характеристики: я использую его на Mac OS X Mavericks с PyRO 4 и Python 3.4.

Заранее спасибо за ваши ответы.

1 ответ

Вы можете использовать инструмент nsc для просмотра базы данных сервера имен. Убедитесь, что вы подключаетесь к правильному серверу имен. Вы увидите, что запрашиваемый вами объект действительно отсутствует. (В противном случае Пиро передаст вам Ури).

Другой совет - проверить, что запрашиваемое вами имя совпадает с тем, что вы зарегистрировали. Также проверьте, если у вас работает несколько серверов имен, возможно, и ваш код их перепутал?

Другие вопросы по тегам