iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 20
0
自我挑戰組

卡牌遊戲開發日記v2020系列 第 20

Day20 來一點 asyncio socket

讓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()

上一篇
Day19 進度
下一篇
Day21 一款卡牌遊戲的指令範例
系列文
卡牌遊戲開發日記v202030

尚未有邦友留言

立即登入留言