class Client:
def __init__(self, host, port, *, timeout=100, loop=None,
pack_encoding='utf-8', unpack_encoding='utf-8',
pack_params=None, unpack_params=None):
self._host = host
self._port = port
self._timeout = timeout
self._loop = loop
self._conn = None
self._msg_id = 0
self._pack_encoding = pack_encoding
self._pack_params = pack_params or dict()
self._unpack_encoding = unpack_encoding
self._unpack_params = unpack_params or dict(use_list=False)
async def create_connection(self):
if self._conn is None:
_logger.debug("connect to {}:{}...".format(self._host, self._port))
reader, writer = await asyncio.open_connection(self._host, self._port, loop=self._loop)
self._conn = Connection(reader, writer,
msgpack.Unpacker(encoding=self._unpack_encoding, **self._unpack_params))
_logger.debug("Connection to {}:{} established".format(self._host, self._port))
async def read_data(self):
while not self._conn.is_closed():
req = None
try:
req = await self._conn.recvall(1000000)
except asyncio.TimeoutError as te:
self._conn.reader.set_exception(te)
except IOError as ie:
break
except Exception as e:
self._conn.reader.set_exception(e)
raise e
if type(req) != tuple:
try:
await _send_error(self._conn, "Invalid protocol", -1)
except Exception as e:
_logger.error("Error when receiving req: {}".format(str(e)))
return
method = None
msg_id = None
args = None
try:
_logger.debug('parsing req: {}'.format(str(req)))
(msg_id, method, args) = _parse_request(req)
_logger.debug('parsing completed: {}'.format(str(req)))
except Exception as e:
_logger.error("Exception {} raised when _parse_request {}".format(str(e), req))
try:
_logger.debug('calling method: {}'.format(str(method)))
ret = method.__call__(*args)
if asyncio.iscoroutine(ret):
_logger.debug("start to wait_for")
ret = await asyncio.wait_for(ret, _timeout)
_logger.debug('calling {} completed. result: {}'.format(str(method), str(ret)))
except Exception as e:
await _send_error(self._conn, str(e), msg_id)
else:
_logger.debug('sending result: {}'.format(str(ret)))
await _send_result(self._conn, ret, msg_id)
_logger.debug('sending result {} completed'.format(str(ret)))
======================================================
async def readdata():
await client.read_data()
loop = uvloop.new_event_loop()
asyncio.set_event_loop(loop)
client = Client('127.0.0.1', 6000)
loop.run_until_complete(client.create_connection())
loop.run_until_complete(readdata())
client.close()
我的要求是与服务器建立连接,并等待服务器中的数据,并在数据可用时执行操作。我有create_connection()
建立连接,并且read_data()
函数等待使用等待self._conn.recvall
的数据输入。但是问题是当数据可用时,它不是在运行而是在连续运行并引发错误。