我尝试运行一个pyro4服务器,在运行Raspbian8(jessie)的Raspberry Pi上运行自定义事件循环。当我使用从套接字.gethostname(),特别是“raspberrypi”,我的客户端脚本找不到名称服务器。当我使用'localhost'作为主机名时,我的客户机脚本能够找到主机名。在/etc/hosts中,“raspberrypi”绑定到127.0.1.1,而“localhost”显然绑定到了127.0.0.1。我原以为这两个地址都绑定到环回接口,所以我不明白为什么一个应该工作而另一个不能工作。在
值得一提的是,在对pyro4代码进行了一些挖掘之后,它看起来像是pyro4的l.463。命名.py,呼叫代理.ping()在使用127.0.1.1时失败,但在使用127.0.0.1时失败,而这正是触发前一个地址失败的根本原因。作为一个火专家,还不清楚这种行为是否在预料之中。有什么想法吗?我想这一定是一个常见的问题,因为大多数(全部?)Debian的风格在/etc/hosts中为这两个地址包含单独的行。在
我在下面附上了代码,重现了这个问题。这基本上只是pyro附带的“eventloop”示例的一个稍微修改的版本。在
在服务器.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()
在客户端.py公司名称:
^{pr2}$在电机控制.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
错误:
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
Pyro服务器的查找依赖于两个方面:
当使用环回适配器绑定名称服务器时,第一个不可用(环回不支持广播套接字)。所以剩下第二个了。 您的问题的答案很简单:直接查找NS_HOST config项的值,默认设置为“localhost”。当localhost解析为127.0.0.1时,它将永远不会连接到127.0.1.1。在
建议:将名称服务器绑定到0.0.0.0或“”(空主机名)上,它应该能够启动广播响应程序。那么你的客户就不会有任何问题找到它。在
或者,只需为您的客户机将NS_HOST设置为127.0.1.1(或您的主机名),如果名称服务器绑定在127.0.1.1上,那么他们也应该能够找到名称服务器
相关问题 更多 >
编程相关推荐