我正在尝试将Pyro的名称服务器变成一个更方便的对象,这样我就可以按照自己的意愿启动和停止它。例如,我希望能够做类似
的事情nameServer = NameServer("localhost")
nameServer.startNS()
[... make some other operations...]
nameServer.stopNS()
nameServer = None
[... make some other operations...]
nameServer = NameServer("localhost")
nameServer.startNS()
使用NameServer类的以下定义:
class NameServer(threadutil.Thread):
def __init__(self, host, isDeamon=True, port=None, enableBroadcast=True,
bchost=None, bcport=None, unixsocket=None, nathost=None, natport=None):
super(NameServer,self).__init__()
self.setDaemon(isDeamon)
self.host=host
self.started=threadutil.Event()
self.unixsocket = unixsocket
self.port = port
self.enableBroadcast = enableBroadcast
self.bchost = bchost
self.bcport = bcport
self.nathost = nathost
self.natport = natport
"""
This code is taken from Pyro4.naming.startNSloop
"""
self.ns_daemon = naming.NameServerDaemon(self.host, self.port, self.unixsocket,
nathost=self.nathost, natport=self.natport)
self.uri = self.ns_daemon.uriFor(self.ns_daemon.nameserver)
internalUri = self.ns_daemon.uriFor(self.ns_daemon.nameserver, nat=False)
self.bcserver=None
if self.unixsocket:
hostip = "Unix domain socket"
else:
hostip = self.ns_daemon.sock.getsockname()[0]
if hostip.startswith("127."):
enableBroadcast=False
if enableBroadcast:
# Make sure to pass the internal uri to the broadcast responder.
# It is almost always useless to let it return the external uri,
# because external systems won't be able to talk to this thing anyway.
bcserver=naming.BroadcastServer(internalUri, self.bchost, self.bcport)
bcserver.runInThread()
def run(self):
try:
self.ns_daemon.requestLoop()
finally:
self.ns_daemon.close()
if self.bcserver is not None:
self.bcserver.close()
def startNS(self):
self.start()
def stopNS(self):
self.ns_daemon.shutdown()
if self.bcserver is not None:
self.bcserver.shutdown()
到目前为止,这么好。它按预期工作。但是,如果我在名称服务器运行时从另一个线程运行命令Pyro4.naming.locateNS()
,那么下次我调用nameServer.stopNS()时,程序会冻结。任何人都知道为什么?编写这样一个NameServer包装器的最佳方法(至少是更好的方法)。
答案 0 :(得分:0)
您可以调整Pyro4存储库中的一个示例。
https://github.com/delmic/Pyro4/blob/master/examples/eventloop/server.py
from __future__ import print_function
import socket
import select
import sys
import Pyro4.core
import Pyro4.naming
if sys.version_info<(3,0):
input=raw_input
print("Make sure that you don't have a name server running already.")
servertype=input("Servertype thread/multiplex (t/m)?")
if servertype=='t':
Pyro4.config.SERVERTYPE="thread"
else:
Pyro4.config.SERVERTYPE="multiplex"
hostname=socket.gethostname()
class EmbeddedServer(object):
def multiply(self, x, y):
return x*y
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)
assert broadcastServer is not None, "expect a broadcast server to be created"
print("got a Nameserver, uri=%s" % nameserverUri)
print("ns daemon location string=%s" % nameserverDaemon.locationStr)
print("ns daemon sockets=%s" % nameserverDaemon.sockets)
print("bc server socket=%s (fileno %d)" % (broadcastServer.sock, broadcastServer.fileno()))
# create a Pyro daemon
pyrodaemon=Pyro4.core.Daemon(host=hostname)
print("daemon location string=%s" % pyrodaemon.locationStr)
print("daemon sockets=%s" % pyrodaemon.sockets)
# register a server object with the daemon
serveruri=pyrodaemon.register(EmbeddedServer())
print("server uri=%s" % serveruri)
# register it with the embedded nameserver directly
nameserverDaemon.nameserver.register("example.embedded.server",serveruri)
print("")
# below is our custom event loop.
while True:
print("Waiting for events...")
# create sets of the socket objects we will be waiting on
# (a set provides fast lookup compared to a list)
nameserverSockets = set(nameserverDaemon.sockets)
pyroSockets = set(pyrodaemon.sockets)
rs=[broadcastServer] # only the broadcast server is directly usable as a select() object
rs.extend(nameserverSockets)
rs.extend(pyroSockets)
rs,_,_ = select.select(rs,[],[],3)
eventsForNameserver=[]
eventsForDaemon=[]
for s in rs:
if s is broadcastServer:
print("Broadcast server received a request")
broadcastServer.processRequest()
elif s in nameserverSockets:
eventsForNameserver.append(s)
elif s in pyroSockets:
eventsForDaemon.append(s)
if eventsForNameserver:
print("Nameserver received a request")
nameserverDaemon.events(eventsForNameserver)
if eventsForDaemon:
print("Daemon received a request")
pyrodaemon.events(eventsForDaemon)
nameserverDaemon.close()
broadcastServer.close()
pyrodaemon.close()
print("done")