This is very simple client for tcp-chat. This is main function:
@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
Application is running. App read data from console, send it into socket. Main loop of application:
@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)
And i have console notification. This function read response from socket and print into console:
@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)
I add this function as callback into ioloop. But this function is never running. How run notification in background? Help my please...
UPD: I create new thread and run notification in new thread:
th = threading.Thread(target=notification, args=(self._stream, ))
th.run()
But it did not help...
input()
is a blocking function; nothing else can happen while it is waiting for input. In order for the application to be responsive you must rework it to avoid blocking functions like input()
, or to perform those functions on a separate thread.