2016-07-26 20 views
0

私は、RabbitMQバックエンドを持つセロリの作業者にタスクを送信して長時間実行する(〜分)計算に使用するTornadoサーバーを持っています。投稿されたタスクは、WebSocketHandler内トルネードコルーチンで得られたされていますTornadoウェブソケットと長時間実行されるセロリのタスク

class MainWSHandler(WebSocketHandler): 
    def open(self): 
     logging.info("Connection opened.") 

    def on_close(self): 
     logging.info("Connection closed.") 

    def on_message(self, message): 
     result = self.submit_task(message) 

     self.write_message("Calculation has been submitted") 

    @gen.coroutine 
    def submit_task(self, params): 
     result = yield gen.Task(long_calculation.apply_async, args=[params]) 

     self.write_message("Completed calculation") 

     return result 

ユーザーが現在開かれているウェブソケットにページを離れることがない場合、これはうまく動作します。それらが実行され、Webソケットが閉じると、返されたメッセージself.write_message("Completed calculation")は、WebSocketClosedErrorで失敗します。ユーザーがしばらくページに戻ってこない場合(つまり、計算が完了するまで)、これは問題ありません。

ただし、ユーザーが計算を実行して、そのページを離れてから計算が終了する前に戻ると、Webソケットが閉じられ、新しいものが開かれているため同じエラーが発生します。これにより、計算完了メッセージがフロントエンドに伝播されなくなります。

私の質問は、同じWebソケットに再接続できますか?あるいは、計算が完了した後に返されたメッセージをユーザーの現在のページに確実に戻す方法を教えてください。

答えて

0

私はこの長い問題をWeb-socket-a-a-a-wp-socketシステムに内在するこの問題に対する構造的解決策があると仮定して、銃を飛ばしたようです。

それはクラス属性

class MainWSHandler(WebSocketHandler): 
    self.clients = {} 

def open(self): 
    logging.info("Connection opened.") 
    self.clients[self.current_user] = self 

で現在開いているウェブソケットを格納し、より効率的であるかもしれません

@gen.coroutine 
def submit_task(self, params): 
    result = yield gen.Task(long_calculation.apply_async, args=[params]) 

    # Retrieve current web socket 
    ws = self.clients[self.current_user] 
    ws.write_message("Completed calculation") 

    return result 

保存されたウェブソケットを使用して、タスクからの応答に対処するために十分です方法(またはいくつかの慣用方法)が、私は今この解決策に満足しています。

関連する問題