2016-07-03 7 views
1

Ich versuche, einen Pyro4-Server mit einer benutzerdefinierten Ereignisschleife auf einem Raspberry Pi mit Raspbian 8 (Jessie) laufen zu lassen. Wenn ich einen Nameserver mit dem Hostnamen von socket.gethostname(), speziell 'raspberrypi', erstelle, kann mein Clientskript den Nameserver nicht finden. Wenn ich 'localhost' als Hostnamen verwende, kann mein Client-Skript den Hostnamen finden. In/etc/hosts ist "raspberrypi" an 127.0.1.1 gebunden, während "localhost" offensichtlich an 127.0.0.1 gebunden ist. Ich hatte gedacht, dass diese beiden Adressen an die Loopback-Schnittstelle gebunden waren, also verstehe ich nicht, warum man arbeiten sollte und nicht die andere.Warum findet Pyro4 den Nameserver nicht unter 127.0.1.1, aber erfolgreich mit 127.0.0.1?

Für was es wert ist, nach etwas in den Pyro4-Code zu graben, sieht es aus wie bei l.463 Pyro4.naming.py, der Aufruf von proxy.ping() scheitert mit 127.0.1.1, aber nicht mit 127.0.0.1 , und das ist letztlich, was den Fehler mit der früheren Adresse auslöst. Da es kein Experte für Pyro ist, ist es nicht klar, ob dieses Verhalten erwartet wird. Irgendwelche Gedanken? Ich nehme an, dass dies ein häufiges Problem sein muss, da die meisten (alle?) Varianten von Debian separate Zeilen in/etc/hosts für diese beiden Adressen enthalten.

Ich habe Code unten angefügt, der das Problem reproduziert. Dies ist im Grunde nur eine leicht modifizierte Version des "eventloop" -Beispiels, das mit Pyro ausgeliefert wird.

server.py:

import socket 
import select 
import sys 
import Pyro4.core 
import Pyro4.naming 

import MotorControl 

Pyro4.config.SERVERTYPE="thread" 
hostname=socket.gethostname() 

print("initializing services... servertype=%s" % Pyro4.config.SERVERTYPE) 
# start a name server with broadcast server as well 
nameserverUri, nameserverDaemon, broadcastServer = Pyro4.naming.startNS(host=hostname) 
pyrodaemon=Pyro4.core.Daemon(host=hostname) 

motorcontroller = MotorControl.MotorControl() 
serveruri=pyrodaemon.register(motorcontroller) 
nameserverDaemon.nameserver.register("example.embedded.server",serveruri) 

# below is our custom event loop. 
while True: 
    nameserverSockets = set(nameserverDaemon.sockets) 
    pyroSockets = set(pyrodaemon.sockets) 
    rs = [] 
    rs.extend(nameserverSockets) 
    rs.extend(pyroSockets) 

    rs,_,_ = select.select(rs,[],[], 0.001) 

    eventsForNameserver=[] 
    eventsForDaemon=[] 
    for s in rs: 
     if s in nameserverSockets: 
      eventsForNameserver.append(s) 
     elif s in pyroSockets: 
      eventsForDaemon.append(s) 
    if eventsForNameserver: 
     nameserverDaemon.events(eventsForNameserver) 
    if eventsForDaemon: 
     pyrodaemon.events(eventsForDaemon) 

    motorcontroller.increment_count() 

nameserverDaemon.close() 
broadcastServer.close() 
pyrodaemon.close() 

client.py:

from __future__ import print_function 
import Pyro4 

proxy=Pyro4.core.Proxy("PYRONAME:example.embedded.server") 
print("count = %d" % proxy.get_count()) 

MotorControl.py

class MotorControl(object): 
    def __init__(self): 
     self.switches = 0 

    def get_count(self): 
     return self.switches 

    def increment_count(self): 
     self.switches = self.switches + 1 

Fehler:

Traceback (most recent call last): 
    File "pyroclient.py", line 5, in <module> 
    print("count = %d" % proxy.get_count()) 
    File "/usr/local/lib/python2.7/dist-packages/Pyro4/core.py", line 248, in __getattr__ 
    self._pyroGetMetadata() 
    File "/usr/local/lib/python2.7/dist-packages/Pyro4/core.py", line 548, in _pyroGetMetadata 
    self.__pyroCreateConnection() 
    File "/usr/local/lib/python2.7/dist-packages/Pyro4/core.py", line 456, in __pyroCreateConnection 
    uri = resolve(self._pyroUri, self._pyroHmacKey) 
    File "/usr/local/lib/python2.7/dist-packages/Pyro4/naming.py", line 548, in resolve 
    nameserver = locateNS(uri.host, uri.port, hmac_key=hmac_key) 
    File "/usr/local/lib/python2.7/dist-packages/Pyro4/naming.py", line 528, in locateNS 
    raise e 
Pyro4.errors.NamingError: Failed to locate the nameserver 

Antwort

0

Pyro-Nameserver-Lookup stützt sich auf zwei Dinge:

  • Broadcast-Lookup
  • direkte Nachschlagen von Hostnamen/IP-Adresse

Die erste ist nicht verfügbar, wenn Sie den Loopback-Adapter zu binden verwenden der Nameserver on (Loopback unterstützt keine Broadcast-Sockets). Wir bleiben also bei der zweiten. Die Antwort auf Ihre Frage ist dann einfach: Die direkte Suche erfolgt nach dem Wert des Konfigurationselements NS_HOST, das standardmäßig auf 'localhost' gesetzt ist. Wenn localhost zu 127.0.0.1 aufgelöst wird, wird nie eine Verbindung zu 127.0.1.1 hergestellt.

Vorschlag: binden Sie den Nameserver auf 0.0.0.0 oder "" (leerer Hostname) und es sollte in der Lage sein, einen Broadcast-Responder zu starten. Dann haben Ihre Kunden kein Problem, sie zu finden.

Alternativ einfach NS_HOST zu 127.0.1.1 (oder der Hostname Ihrer Box) für Ihre Kunden eingestellt und sie sollten den Name-Server als auch lokalisieren können, wenn sie auf 127.0.1.1

gebunden sind