python--websocket

安装

websocket不是python的自带库,需要下载安装:

pip install websockets

案例

client:

复制代码
import asyncio
import websockets

async def hello():
    uri = "ws://localhost:8765"
    async with websockets.connect(uri) as websocket:
        # 发送消息给服务器
        message = "Hello, WebSocket!"
        await websocket.send(message)
        print(f"发送消息: {message}")

        # 接收服务器的回复
        response = await websocket.recv()
        print(f"收到回复: {response}")

if __name__ == "__main__":
    asyncio.run(hello())

serve:

复制代码
import asyncio
import websockets

async def echo(websocket):
    """处理单个客户端的连接,接收消息并原样返回"""
    async for message in websocket:
        print(f"收到客户端消息: {message}")
        # 将消息回显给客户端
        await websocket.send(f"服务器回显: {message}")

async def main():
    # 启动 WebSocket 服务器,绑定到本地 8765 端口
    async with websockets.serve(echo, "localhost", 8765):
        print("WebSocket 服务器已启动,监听 ws://localhost:8765")
        await asyncio.Future()  # 保持服务器运行

if __name__ == "__main__":
    asyncio.run(main())

每一个async的作用--链接

1. async with websockets.connect(uri) as websocket:

  • 异步上下文管理器 。进入该上下文时,会执行 websockets.connect(uri) 的异步操作(建立 WebSocket 连接),并且等待 连接建立完成,期间当前协程会暂停,让出事件循环。

  • 退出上下文时,会自动等待连接关闭的异步操作完成。

  • async with 保证了在进入和退出时正确地处理异步资源的获取与释放。

2. await websocket.send(message)

  • 等待 发送操作完成。websocket.send 是一个异步方法,它将消息写入缓冲区并可能等待网络发送完成。使用 await 后,当前协程(调用send()的协程)会暂停,直到数据发送完毕或出错,才会返回当前协程,期间事件循环可以执行其他任务。

  • 注意:这里的"等待发送完成"并不一定意味着数据已经到达对方,而是指数据已进入内核缓冲区,可以继续发送后续消息。

3. await websocket.recv()

  • 等待 接收服务器的回复。这是一个异步阻塞操作:如果没有消息到达,当前协程 (调用recv()的协程)会暂停,让出事件循环;当收到完整消息后,协程恢复并返回消息内容。

  • 这体现了异步 I/O 的核心:在等待网络数据时,CPU 可以处理其他任务。

4. async for message in websocket:

  • 异步迭代websocket 对象是一个异步可迭代对象,每次迭代都会等待下一条消息的到来。

  • 循环体会在收到消息时执行,当没有消息时,当前协程暂停,事件循环可以运行其他客户端的协程。

  • 这种写法避免了手动调用 recv() 和循环控制,是处理消息流的简洁方式。

-- async 的核心目的就是让协程在"没事干"(比如等待网络、磁盘 I/O)的时候主动让出事件循环的控制权,从而让其他就绪的协程得以执行。

--await 则是调用了某个异步接口(async def修饰)之后,异步接口没有完成之前,当前执行的协程不会往下执行,需要等待异步接口完成,期间如果异步接口需要等待,则当前协程则会让出事件循环控制权。

关键字/语法 作用
async def 定义协程函数,调用返回协程对象
async with 异步上下文管理器,进入和退出时自动等待异步操作
async for 异步迭代器,每次迭代自动等待下一个元素
await 挂起当前协程,等待一个可等待对象(协程、任务、Future、异步方法等)完成,期间事件循环运行其他任务

这样每次调用一个接口的时候都要加上一个async就很麻烦,既然已经使用async def定义协程函数了,为什么协程函数里边还要在每一个异步函数之前加上await,async with已经修饰这代码块了,为什么代码快中还要在调用的每一个函数前加上await?

1. async def 只是定义了一个协程工厂

当你写:

复制代码
async def hello():
    ...

你只是定义了一个协程函数 。调用它(例如 hello())并不会执行函数体内的任何代码,而是立即返回一个协程对象 。这个协程对象需要被事件循环调度(比如通过 awaitasyncio.create_task)才能真正开始执行。

换句话说:async def 只是让函数具备了"可暂停"的能力,但不会自动运行。

2. await 是实际执行异步操作的指令

在协程内部,当你调用一个异步函数 (比如 websocket.send(message)),它返回的是一个可等待对象 (awaitable),通常是另一个协程对象。如果你不加 await,这个协程对象就被丢弃了,里面的代码永远不会执行。这就像你写了一个函数却没有调用它。

因此,必须使用 await 来告诉事件循环:"请执行这个异步操作,并在它完成之前,我可以让出控制权。" 正是 await 触发了真正的 I/O 操作,并让协程在等待期间挂起。

接口

websocket.serve

复制代码
        async with websockets.serve(self.handler, self.host, self.port):
            print(f"WebSocket 服务器已启动,监听 {self.host}:{self.port}")
            await asyncio.Future()

既然是服务端,那么应该不用指定ip,为什么serve还要指定ip; asyncio.Future()的作用为什么可以保持服务器运行?

问题1:为什么服务端还需要指定 IP?

在网络编程中,服务端必须明确指定要监听的地址和端口 。这是因为一台计算机可能拥有多个网络接口(网卡)(例如:本地回环 127.0.0.1、局域网 IP、公网 IP 等)。通过指定 IP,你可以控制服务端仅接受来自特定接口的连接:

  • "localhost""127.0.0.1":只允许本机上的客户端连接,外部机器无法访问。常用于本地开发或测试。

  • "0.0.0.0":监听所有可用的网络接口,允许任何能到达该主机的客户端连接(包括本机和远程)。

  • 具体的局域网 IP:只允许通过该 IP 地址访问。

问题2:await asyncio.Future() 为什么能保持服务器运行?

理解 asyncio.Future

asyncio.Future 是一个占位符对象,代表一个将来会完成 的异步操作的结果。它类似于并发编程中的"Promise"。默认情况下,一个新建的 Future 对象处于未完成 状态,除非你手动调用 .set_result().set_exception() 来让它完成。

相关推荐
taxunjishu2 小时前
塔讯总线协议转换信捷 PLC 对接 TCP/IP 设备实战方案
网络·物联网·自动化
墨神谕2 小时前
什么是Socket
websocket·网络协议
带娃的IT创业者2 小时前
WeClaw WebSocket 连接中断诊断:从频繁掉线到稳定长连的优化之路
python·websocket·网络协议·php·fastapi·实时通信
IpdataCloud2 小时前
指纹浏览器为什么要自建IP检测?基于IP数据云离线库的架构实践
数据库·网络协议·tcp/ip·架构·edge浏览器
taxunjishu4 小时前
半导体晶圆制造车间 SITRANS P 仪表与 V90 伺服系统精密控制应用
网络·物联网·自动化
雷帝木木4 小时前
Flutter for OpenHarmony:Flutter 三方库 cbor 构建 IoT 设备的极致压缩防窃协议(基于标准二进制 JSON 表达格式)
网络·物联网·flutter·http·json·harmonyos·鸿蒙
齐齐大魔王4 小时前
虚拟机网络无法连接
linux·网络·c++·python·ubuntu
ht巷子5 小时前
boost.asio网络学习:Http Server
网络·c++·http
-许平安-5 小时前
MCP项目笔记三(server)
网络·c++·笔记·mcp