Не удалось использовать await в asyncio.protocol - PullRequest
0 голосов
/ 12 апреля 2020

Я пытаюсь построить сервер эхо-ретрансляции, используя asyncio.protocol, он работает следующим образом:

1)listen port 16666, try to get message from sender
2)forward message to answer program who listen port 19999
3)forward message from answer program to sender

Мой код следующий:

#!/usr/bin/python3
# -*- coding:utf-8 -*-

import sys
import time
import asyncio
import os
import re
import atexit
import signal
import subprocess
import json
import subprocess
import hashlib

async def tcp_echo_client(message):
    global event_loop
    reader, writer = await asyncio.open_connection('127.0.0.1', 19999, loop=event_loop)

    print('Send: %r' % message)
    writer.write(message.encode())

    data = await reader.read(100)
    result = 'Received: %r' % data.decode()

    print('Close the socket')
    writer.close()
    return result


class EchoServer(asyncio.Protocol):

    def connection_made(self, transport):
        self.transport = transport
        self.address = transport.get_extra_info('peername')
        print('Connection accepted')

    def data_received(self, data):
        recv = data.decode()
        print('Receive: [{}]'.format(recv))
        print('relay got msg from ctl: {}'.format(recv))
        result = await tcp_echo_client(recv)    # problem here !!!
        self.transport.write(result.encode())

    def eof_received(self):
        print('received EOF')
        if self.transport.can_write_eof():
            self.transport.write_eof()

    def connection_lost(self, error):
        print('closing {}'.format(cfg.DEBUG_MODE))
        super().connection_lost(error)


TCP_LISTEN_PORT = 16666
event_loop = asyncio.get_event_loop()
factory = event_loop.create_server(EchoServer, '127.0.0.1', TCP_LISTEN_PORT)
server = event_loop.run_until_complete(factory)
try:
    event_loop.run_forever()
finally:
    server.close()
event_loop.close()

Когда я запускаю эту программу что сказал мне "неверный синтаксис". Документ сказал мне, что «await может использоваться только внутри функции asyn c def». Поэтому я пытаюсь удалить ключевое слово await, но оно выдает исключение [AttributeError: объект coroutine 'не имеет атрибута «закодировать»] при получении сообщения из ответа.

Я просто хочу узнать, как я могу сделать клиент в классе asyncio.protocol работает. Спасибо!

...