caracteristica de yield from e que o resultado do self.leitor.readline() e retornado e no caso, armazenado na variavel dados.A execucao segue normalmente e nosso servidor envia a hora e a data atual, veja que uma linha foi acrescentada ao final da string. Este fim de linha e importante, pois como nosso protocolo e em formato texto e orientado a linhas, esperamos o enter (CR) para processar o comando ou a resposta.Depois de escrever a resposta, usamos self.escritor.drain() que e uma outra corotina. Esta nova corotina nao completa ate o que o buffer de escrita seja enviado. Desta forma, podemos garantir que os dados foram enviados (ainda que nao possamos ter certeza se estes foram recebidos pelo cliente) antes de continuarmos. Como usamos yield from com esta corotina, a execucao e suspensa ate que o drain seja completado.Como usamos Python 3.4, os dados sao do tipo byte e nao string. A funcao byteToStr converte de bytes para string, usando a codificacao UTF-8. Esta funcao sera apresentada no programa common.py, compartilhando rotinas uteis tanto para nosso cliente quanto para nosso servidor. Para facilitar o processamento de comandos, retiramos os espacos em branco do inicio e fim do comando, inclusive enter (CR) e LF, e convertemos o resultado para minusculas com lower. Se o comando for igual a "sair", chamamos o metodo close de self.transporte para encerarmos a conexao. Veja que ao fecharmos a conexao, finalmente retornamos como em uma funcao normal, utilizando return e terminando assim a execucao de nossa corotina gerencia.O metodo connection_lost e chamado quando a desconexao do cliente e detectada. O numero de conexoes ativas e decrementado e o metodo connection_lost da superclasse e chamado. O parametro exp contem None caso seja uma desconexao normal ou a excecao em caso de erro. Neste exemplo nao estamos tratando os possiveis erros para nos concentrarmos no asyncio.Ja o metodo data_received e chamado sempre que dados forem recebidos pelo transporte. Os dados recebidos sao passados como parametro (dados). Aqui, inclui algumas funcoes de debug que exibem os dados em formato hexadecimal, string e UTF-8. Estas funcoes sao necessarias para verificarmos se os dados estao chegando no formato esperado. Voce pode executar um teste com um programa de telnet classico, como o Putty no Windows, mas nao esqueca de desativar a opcao de negociacao do protocolo, para evitar que comandos que nao interpretamos sejam enviados, ou simplesmente, teste com o cliente que e apresentado logo abaixo.Um detalhe muito importante de data_received e a chamada do metodo self.leitor.feed_data, que envia os dados para o leitor, responsavel por quebrar os dados em linhas.Em nosso programa principal, obtemos o loop de eventos com get_event_loop() e criamos uma corotina que inicializa nosso servidor com loop.create_server. Em create_server, informamos o endereco que nosso servidor ira escutar (ip e porta). Veja que a classe EchoServer foi passada como protocol factory.Ao chamarmos loop.run_until_complete(coro), o loop de eventos roda ate que a corotina criada pelo create_server termine, retornando um objeto servidor, utilizado para parar o servidor e para ter acesso a todas as conexoes, mas isso fica para outro post.Chamamos loop.run_forever() para ativar