我正在對抗這個問題約一週,而且我不知道在哪裏尋找解決方案。當我嘗試查找註冊對象時,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。
在此先感謝您的答覆。