2014-10-09 65 views
0

我正在對抗這個問題約一週,而且我不知道在哪裏尋找解決方案。當我嘗試查找註冊對象時,PyRO 4 - 查找失敗

正如標題所說,只要我成功註冊一個pyro對象,我試圖在NS上找到它,以便與它一起操作,但查找失敗。

我後我的代碼的簡化版本,使情況更加清晰:

服務器是在熱裂解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() 

Connection類提供找上了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)) 

所以,基本上,這就是我正在做的。

問題是,在find_obj()方法(包含在Connection類中)內部嘗試查找NS上的遠程對象時,查找失敗,但我確信遠程對象已成功註冊。

給出的錯誤是來自Pyro4.errors.NamingError的「未知名稱」。

我真的不知道爲什麼它不工作...

而且規格:我運行它在Mac OS X小牛,有PYRO 4和Python 3.4。

在此先感謝您的答覆。

回答

0

您可以使用nsc工具查看名稱服務器的數據庫。確保連接到正確的名稱服務器。你會看到你請求的對象真的不在那裏。 (否則Pyro會把你的uri給你)。

另一個提示可能是檢查您要求的名稱與您註冊的名稱完全相同。另外檢查你是否有多個名稱服務器運行,也許你的代碼讓他們混合起來?