目前,我有一个应用程序有两个服务器:第一个处理订单并单独响应,第二个广播结果给其他感兴趣的订阅者。它们需要从不同的端口提供服务。我可以开始()它们两个,但我只能得到一个或另一个到serve_forever(),因为我读到它是一个阻塞函数。我正在寻找有关如何防止服务器退出的想法。缩写代码如下:
def main():
stacklist = []
subslist = []
stacklist.append(CreateStack('stuff'))
subslist.append(Subscription('stuff'))
bcastserver = BroadcastServer(subslist) # creates a new server
tradeserver = TradeServer(stacklist) # creates a new server
bcastserver.start() # start accepting new connections
tradeserver.start() # start accepting new connections
#bcastserver.serve_forever() #if I do it here, the first one...
#tradeserver.serve_forever() #blocks the second one
class TradeServer(StreamServer):
def __init__(self, stacklist):
self.stacklist = stacklist
StreamServer.__init__(self, ('localhost', 12345), self.handle)
#self.serve_forever() #If I put it here in both, neither works
def handle(self, socket, address):
#handler here
class BroadcastServer(StreamServer):
def __init__(self, subslist):
StreamServer.__init__(self, ('localhost', 8000), self.handle)
self.subslist = subslist
#self.serve_forever() #If I put it here in both, neither works
def handle(self, socket, address):
#handler here
也许我只是需要一种方法来防止两人退出,但我不确定如何。最后,我希望两台服务器永远监听传入的连接并处理它们。
答案 0 :(得分:2)
我知道这个问题的答案可以接受,但是有一个更好的答案。我将其添加给像我这样的人,这些人以后可以找到此帖子。
如gevent documentation about servers中所述:
BaseServer.serve_forever()方法调用BaseServer.start(),然后等待直到被中断或服务器停止。
所以您可以这样做:
def main():
stacklist = []
subslist = []
stacklist.append(CreateStack('stuff'))
subslist.append(Subscription('stuff'))
bcastserver = BroadcastServer(subslist) # creates a new server
tradeserver = TradeServer(stacklist) # creates a new server
bcastserver.start() # starts accepting bcast connections and returns
tradeserver.serve_forever() # starts accepting trade connections and blocks until tradeserver stops
bcastserver.stop() # stops also the bcast server
gevent introduction documentation解释了为什么这样做:
与其他网络库不同,尽管其方式与 eventlet,gevent以专用方式隐式启动事件循环 绿色。没有反应堆,您必须调用run()或dispatch() 功能开启。当gevent的API中的函数想要阻止时,它会 获取gevent.hub.Hub实例-运行 事件循环-并切换到该循环(据说Greenlet产生了 控制到集线器)。
serve_forever()阻塞时,它不会阻止任何服务器继续通信。
注意:在上面的代码中,交易服务器是决定整个应用程序何时停止的服务器。如果要由广播服务器决定,则应在start()
和serve_forever()
呼叫中交换它们。
答案 1 :(得分:1)
好的,我能够使用线程和gevent的monkeypatch库来做到这一点:
from gevent import monkey
def main():
monkey.patch_thread()
# etc, etc
t = threading.Thread(target=bcastserver.serve_forever)
t.setDaemon(True)
t.start()
tradeserver.serve_forever()
答案 2 :(得分:0)
在自己的Python实例中启动每个服务器循环(每个gevent一个控制台)。我从未理解尝试从一个程序运行多个服务器。您可以多次运行同一台服务器,并使用像nginx这样的反向代理来相应地进行负载均衡和路由。