讓socket可以用async的方式接收資料
本篇所參考的相關文件:
asyncio
利用 coroutine 機制完成的非同步 I/O 函式庫,它讓以前常常要使用 callback 運行程式的做法變成比較直觀的 async/await 寫法。
asyncio/Event Loop
所有 asyncio 應用程式的核心,它控管所有使用到的 asyncio 事件。
asyncio/Futures
被包裝成 async樣子的 callback 程式段落。
asyncio/Exceptions
定義 Futures 在執行時的異常,有 CancelledError, InvalidStateError, TimeoutError
asyncio/Streams
封裝過的高階串流資料處理介面,不用處理到底層的I/O操作
之所以選用 async 的方式是因為這樣 socket 接收資料的部份可以放在自己的eventLoop裡面,而不是以往的 while True。
可以看一下範例感受一下差別:
import asyncio
async def tcp_echo_client(message, loop):
    reader, writer = await asyncio.open_connection('127.0.0.1', 8888,
                                                   loop=loop)
    print('Send: %r' % message)
    writer.write(message.encode())
    data = await reader.read(100)
    print('Received: %r' % data.decode())
    print('Close the socket')
    writer.close()
message = 'Hello World!'
loop = asyncio.get_event_loop()
loop.run_until_complete(tcp_echo_client(message, loop))
loop.close()
import asyncio
async def handle_echo(reader, writer):
    data = await reader.read(100)
    message = data.decode()
    addr = writer.get_extra_info('peername')
    print("Received %r from %r" % (message, addr))
    print("Send: %r" % message)
    writer.write(data)
    await writer.drain()
    print("Close the client socket")
    writer.close()
loop = asyncio.get_event_loop()
coro = asyncio.start_server(handle_echo, '127.0.0.1', 8888, loop=loop)
server = loop.run_until_complete(coro)
# Serve requests until Ctrl+C is pressed
print('Serving on {}'.format(server.sockets[0].getsockname()))
try:
    loop.run_forever()
except KeyboardInterrupt:
    pass
# Close the server
server.close()
loop.run_until_complete(server.wait_closed())
loop.close()