2017-11-19 9 views
-1
class Client(tornado.websocket.WebSocketHandler): 
    def open(self): 
     print "Connection is opened" 

    def on_message(self, message): 
     self.Process(message) 

    def on_close(self): 
     print "socket closed" 

Nehmen Sie den obigen Code in Python/Tornado. Eine Instanz von Client wird erstellt, wenn ein neuer Websocket-Client eine Verbindung zum Server herstellt. Das Problem ist, self.process(message) dauert Minuten und der gesamte Handler ist blockiert (keine Verbindung mehr akzeptieren oder Nachricht zu empfangen), solange self.process(message) auf Prozess ist. Gibt es eine Lösung, um dieses Hindernis zu überwinden?Tornado nicht blockierende Websocket Server-Implementierung

+0

Sie können versuchen, "self.process" -Methode in einem separaten Thread ausführen. Wenn es sich um eine CPU-intensive Aufgabe handelt, gibt es keine Alternative, sie in einem separaten Thread auszuführen. Wenn es sich um eine netzwerkgebundene Aufgabe handelt, können Sie versuchen, eine asynchrone Bibliothek für diese Aufgabe zu finden oder Ihre eigene zu schreiben. – xyres

+0

Bearbeiten [einige Sprache war im letzten Kommentar verwirrend]: Sie können die Anzahl der Threads durch die ['max_workers'] (https://docs.python.org/3.5/library/concurrent.futures.html#concurrent) begrenzen. futures.ThreadPoolExecutor) Argument. Zu einer bestimmten Zeit wird also nur eine begrenzte Anzahl von Anfragen bearbeitet und der Rest wird in die Warteschlange gestellt. – xyres

+0

Ich habe gerade 'ThreadPoolExecutor' gefunden. Ich denke, das ist eine gute Bibliothek dafür. –

Antwort

0

Hier ist ein Basic-Code zum Einstieg mit ThreadPoolExecutor:

import concurrent.futures 

# create a `ThreadPoolExecutor` instance 
executor = concurrent.futures.ThreadPoolExecutor(max_workers=8) 


class Client(tornado.websocket.WebSocketHandler): 

    def on_message(self, message): 
     # ask `executor` to run `self.process` in a thread 
     executor.submit(self.process, message) 

    def process(self, message): 
     # do something blocking ... 
     return processed_message 

Wenn Sie die Nachricht in on_message nach der Verarbeitung darauf zugreifen möchten, haben Sie es mit gen.coroutine zu dekorieren und dann yield Die executor.submit(...):

from tornado import gen 

class Client(tornado.websocket.WebSocketHandler): 

    # decorate on_message with gen.coroutine 
    @gen.coroutine 
    def on_message(self, message): 
     # now use the yield keyword 
     processed_message = yield executor.submit(self.process, message) 
     # do something with processed_message 

    def process(self, message): 
     # do something blocking ... 
     return processed_message 
+0

wie lange diese 8 Arbeiter am Leben bleiben? Angenommen, die erste Anforderung wurde verarbeitet, die Threads des Pools werden beendet? oder noch am Leben? –

+0

@MehrdadDadvand Die Arbeiter im Pool bleiben immer am Leben. Dies ist wichtig, um die Zeit zu reduzieren, die zum Starten und Stoppen von Threads benötigt wird. – xyres

+0

das ist ausgezeichnet. vielen Dank. es half –

Verwandte Themen