1

現在、2 つのサーバーを持つアプリケーションがあります。最初のサーバーは注文を処理して個別に応答し、2 番目のサーバーは結果を他の関心のあるサブスクライバーにブロードキャストします。それらは異なるポートから提供される必要があります。両方を start() できますが、ブロッキング関数であると読んでいるため、 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

おそらく、この 2 つが終了しないようにする方法が必要なだけかもしれませんが、方法がわかりません。最後に、両方のサーバーが着信接続を永遠にリッスンして処理するようにします。

4

3 に答える 3

2

この質問には受け入れられた回答があることは知っていますが、より良い回答があります。後でこの投稿を見つけた私のような人のために追加しています。

サーバーに関するgeventドキュメントで説明されているように:

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 の紹介ドキュメントでは、これが機能する理由について説明しています。

他のネットワーク ライブラリとは異なり、eventlet と同様の方法で、gevent は専用の greenlet で暗黙的にイベント ループを開始します。run() または dispatch() 関数を呼び出さなければならないリアクターはありません。gevent の API からの関数がブロックする必要がある場合、関数は gevent.hub.Hub インスタンス (イベント ループを実行する特別なグリーンレット) を取得し、それに切り替えます (グリーンレットがハブに制御を渡したと言われています)。

serve_forever() がブロックされても、どちらのサーバーも通信を継続できなくなりません。

注: 上記のコードでは、アプリケーション全体がいつ停止するかを決定するのはトレーダー サーバーです。ブロードキャスト サーバーにこれを決定させたい場合は、start()とのserve_forever()呼び出しでそれらを交換する必要があります。

于 2018-08-10T14:25:27.517 に答える
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()
于 2013-08-27T12:36:43.950 に答える