Python:WebSocket通信遇Coroutine was never awaited报错,添加await后触发TypeError问题求助
解决WebSocket协程未等待与数据类型错误的问题
咱们来一步步拆解你遇到的两个问题,顺便修复代码里的其他小坑:
第一个错误:Coroutine was never awaited
这个问题的根源很直接:websockets库的send()方法是异步协程函数,你直接调用P1_UserID.send({"Player": 1})的时候,只是创建了一个待执行的协程对象,但根本没让它跑起来,所以Python会抛出这个警告(甚至错误)。解决方法就是给send()前面加await,不过这又引出了第二个问题。
第二个错误:TypeError: data is a dict-like object
websocket.send()方法只认字符串、字节这类可直接传输的格式,你直接传Python字典它肯定懵——它不知道怎么把字典转成WebSocket能传输的二进制/文本数据。所以得先把字典序列化成JSON字符串,这就需要用到json模块。
修正后的完整代码
我还帮你补全了缺失的register函数,加了断开连接时的清理逻辑,以及把端口输入转成整数(原代码用字符串会报错):
import asyncio import websockets import logging import json # 新增:用来把字典转成JSON字符串 logging.basicConfig() IPAddress = input("Configure IP Address: ") Port = int(input("Configure Port: ")) # 转成整数,websocket服务要求端口是整数 P1_UserID = None # 初始化为None比空字符串更清晰 P2_UserID = None USERS = set() async def register(websocket): # 补全你调用但没定义的register函数:把连接加入用户集合 USERS.add(websocket) async def unregister(websocket): # 新增断开连接时的清理逻辑:避免旧连接占着玩家位置 USERS.discard(websocket) global P1_UserID, P2_UserID if websocket == P1_UserID: P1_UserID = None elif websocket == P2_UserID: P2_UserID = None async def register_player(websocket): global P1_UserID, P2_UserID if not P1_UserID: P1_UserID = websocket # 先把字典转成JSON字符串,再用await执行send协程 await websocket.send(json.dumps({"Player": 1})) print("Player 1 registered successfully") elif not P2_UserID: P2_UserID = websocket await websocket.send(json.dumps({"Player": 2})) print("Player 2 registered successfully") print(f"Current P1 connection: {P1_UserID}") print(f"Current P2 connection: {P2_UserID}") async def server(websocket, path): await register(websocket) try: await register_player(websocket) # 监听客户端发来的消息,可选转发给另一个玩家 async for message in websocket: print(f"Received from client: {message}") # 如果两个玩家都在线,把消息转发给对方 if P1_UserID and P2_UserID: if websocket == P1_UserID: await P2_UserID.send(message) else: await P1_UserID.send(message) finally: # 不管连接怎么断开,都清理资源 await unregister(websocket) start_server = websockets.serve(server, IPAddress, Port) asyncio.get_event_loop().run_until_complete(start_server) asyncio.get_event_loop().run_forever()
关键修正点说明
- 序列化字典:用
json.dumps()把{"Player": 1}这类字典转成"{\"Player\":1}"格式的字符串,符合WebSocket的传输要求。 - await协程:所有
send()调用前都加了await,确保协程被执行,解决“协程未等待”的错误。 - 资源清理:新增
unregister函数,玩家断开连接时会清空对应的全局变量,避免下次新连接无法注册。 - 端口类型修正:把输入的端口字符串转成整数,
websockets.serve()要求端口是整数类型。
你可以用wscat这类WebSocket客户端工具测试:
wscat -ws ws://你的IP地址:端口号
连接后就能收到服务器发送的玩家编号,发送消息还能转发给另一个连接的玩家~
内容的提问来源于stack exchange,提问作者Joy Singh
相关产品推荐
相关产品推荐

