2017-12-10 4 views
0

Ich versuche, einen Terminal wie Funktion in einer Web-Anwendung mit Tornados, WebSockets und jetzt bei der Umsetzung der so etwas wie die input Funktion, wo die Koroutine Ausführung pausiert und wartet, bis die Benutzereingaben etwasWie wird von einer asynchronen Warteschlange auf nicht blockierende Weise konsumiert?

stecke asyncio.Queue

Ich bin zu erstellen

Mein erster Entwurf war ein Sitzungsobjekt für jeden Benutzer erstellen send, receive und next Methoden

  • send Methode wird verwendet, Umsetzung senden Nachricht an Benutzer
  • receive Methode zur Benutzernachrichten empfangen und leiten sie an Handler
  • next Methode Ausführung Handler bis zum nächsten Benutzer Nachricht zu pausieren

Session-Klasse:

import asyncio 

class Session: 
    def __init__(self, ws_handler): 
     self.ws_handler = ws_handler 
     self.cbs = list() 
     self.q = asyncio.Queue() 
     self.waiting = False 

    async def consume(self): 
     return await self.q.get() 

    async def next(self): 
     self.waiting = True 
     return await self.consume() 

    def send(self, response): 
     self.ws_handler.write_message(response.bytes()) 

    async def receive(self, msg): 
     if self.waiting: 
      await self.q.put(msg) 
      self.waiting = False 
      return 
     await views.authenticate(self, msg) 
     for cb in self.cbs: 
      print('calling', cb.__name__) 
      await cb(self, msg) 

    def register(self, *callbackss): 
     self.cbs += list(*callbackss) 

und dumm genug zu sein, dachte ich, ich könnte es so verwenden:

async def handle_input(some_message): 
    session.send("Please enter your name") 
    name = await session.next() 
    # do some stuff 

Dies funktionierte tatsächlich in einer Weise, dass die handle_input wie erwartet pausiert wurde, aber natürlich war der ganze Server für immer blockiert.

Meine Frage ist, wie man richtig àsyncio.Queue oder jede andere Strategie, um die input wie Funktionalität

I 3.6 und Tornado bin mit Python zu erreichen verwenden, um 3.5.2

Antwort

0

Update:asynctio.Queue funktioniert nicht mit Tornados Ereignisschleife. Deshalb erhalten Sie blockiert Verhalten. Siehe Ich öffnete darüber.

Sie haben zwei Möglichkeiten jetzt:

  1. Verwenden tornado.queues.Queue statt asyncio.Queue.
  2. Oder verwenden Sie die Ereignisschleife von asyncio anstelle von Tornados Ereignisschleife. Siehe docs.
Verwandte Themen