2015-12-07 2 views
0

Это очень простой клиент для tcp-chat. Это основная функция:Tornado не работает callback

@gen.coroutine 
def main(): 
    factory = TCPClient() 
    stream = yield factory.connect(af=socket.AF_INET, **options.options.group_dict("connect")) 
    # Add notification callback 
    ioloop.IOLoop.instance().add_callback(notification, stream) 
    # Run application 
    app = Application(stream) 
    app.run() 

if __name__ == '__main__': 
    try: 
     main() 
     ioloop.IOLoop.instance().start() 
    except KeyboardInterrupt: 
     pass 

Приложение работает. Приложение считывает данные с консоли, отправляет их в сокет. Основная петля применения:

@gen.coroutine 
def run(self): 
    while True: 
     try: 
      s = input('> ') 
      command, text = self._parse_command(s) 
      handler = self.handler(self._stream, self) 
      yield handler.execute_command(command, text) 
     except Exception as e: 
      print(e) 

И у меня есть консольное уведомление. Эта функция считывает ответ сокета и печатает на консоль:

@gen.coroutine 
def notification(stream): 
    message_length = yield stream.read_bytes(2) 
    length = struct.unpack("!H", message_length)[0] 
    message = yield stream.read_bytes(length) 
    # request = Message.unpack(message=message) 
    sys.stdout.write('\r'+' '*(len(readline.get_line_buffer())+2)+'\r') 
    print(message) 
    sys.stdout.write('> ' + readline.get_line_buffer()) 
    sys.stdout.flush() 
    ioloop.IOLoop.instance().add_callback(notification, stream) 

Я добавляю эту функцию в качестве обратного вызова в ioloop. Но эта функция никогда не работает. Как запустить уведомление в фоновом режиме? Помогите, пожалуйста, мой ...

UPD: создать новую нить и запустить уведомление в новом потоке:

th = threading.Thread(target=notification, args=(self._stream,)) 
th.run() 

Но это не помогло ...

ответ

1

input() является функцией блокировки ; ничего не может произойти, пока он ждет ввода. Чтобы приложение было отзывчивым, вы должны его переработать, чтобы избежать блокировки функций, таких как input(), или для выполнения этих функций в отдельном потоке.

+0

Можете ли вы показать мне простой пример? – Wolkodav

+0

Пример для запуска tornado coroutine в новой теме – Wolkodav

+0

Вы не можете запустить сопрограмму в новом потоке; все сопрограммы должны запускаться в потоке IOLoop. Вы будете запускать 'input()' в другом потоке с помощью ThreadPoolExecutor. –

Смежные вопросы