赞
踩
这两天碰到了有关 websocket 开发的应用,使用的是 python 中的 websockets
来实现的。
因为大多数教学中的 websockets
使用异步方式工作,而 python 中的 websockets
是通过 asyncio
来实现异步操作的,而这两者在使用的时候往往由于教程过于简单,导致在面对一些复杂应用的时候自己会弄不清异步的处理逻辑。
因此记录一下 asyncio
和 websockets
工作的基本原理,便于以后使用两者开发更复杂的异步应用,或者理解复杂异步应用的逻辑。
使用 websockets
的一个经典例子如下所示:
# server.py import asyncio import websockets async def on_message(websocket, path): async for message in websocket: print(f"收到消息: {message}") await websocket.send(f"你发送的消息是: {message}") if __name__ == "__main__": host = "localhost" port = 8888 asyncio.get_event_loop().run_until_complete(websockets.serve(on_message, host , port)) asyncio.get_event_loop().run_forever() # client.py import asyncio import websockets async def hello(uri): async with websockets.connect(uri) as websocket: message = input("请输入消息: ") await websocket.send(message) response = await websocket.recv() print(f"服务器响应: {response}") if __name__ == "__main__": host = "localhost" port = 8888 asyncio.get_event_loop().run_until_complete(hello(f"ws://{host}:{port}))
从表现看来上面的例子非常直观:服务端启动,客户端连接客户端,并向客户端发送消息,服务端接收后向客户端回传一个消息,结束。
那具体发生了什么呢?首先要从 asyncio
说起
asyncio
是 Python 3.6 引入的标准库内容 中用于实现异步编程的标准库,而协程则是异步编程中的一种核心概念。asyncio
提供了一个事件循环(Event Loop),允许在单线程中执行多个协程,处理异步任务、事件和 I/O 操作。
协程本质上仍然是单线程,比较适合需要大量等待的任务(网络通讯、文件 IO 等),否则不能提升程序的效率。
Python 3.5 之前协程主要是生成器协程,使用生成器定义,用 yield
关键字让出控制权,并且可以暂停和恢复。
Python 3.6 之后协程主要是函数协程,使用 async def
关键字定义的函数对象,用 await
关键字等待异步操作完成。
本着用新不用旧的原则,下面的提及的都是 Python 3.6 之后的用法,但函数协程本质上也能当成生成器看待,只是 python 解释器提供更高级的方法来控制运行。
注:
await
之后只能接awaitable
对象,python 原生提供三类awaitable
对象:
- Coroutine - 协程,使用
async def
声明的异步函数- Future -
asyncio.Future
是一个实现了awaitable
接口的对象,代表了一个异步操作的结果。可以使用asyncio.ensure_future
或asyncio.create_task
创建Future
对象- Task -
asyncio.Task
是Future
的子类,表示一个异步操作的执行。通常使用asyncio.create_task
创建任务另外,任何实现了
__await__
方法的类实例都是awaitable
对象。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。