You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

关键修正点说明

  1. 序列化字典:用json.dumps()把{"Player": 1}这类字典转成"{\"Player\":1}"格式的字符串,符合WebSocket的传输要求。
  2. await协程:所有send()调用前都加了await,确保协程被执行,解决“协程未等待”的错误。
  3. 资源清理:新增unregister函数,玩家断开连接时会清空对应的全局变量,避免下次新连接无法注册。
  4. 端口类型修正:把输入的端口字符串转成整数,websockets.serve()要求端口是整数类型。

你可以用wscat这类WebSocket客户端工具测试:

wscat -ws ws://你的IP地址:端口号

连接后就能收到服务器发送的玩家编号,发送消息还能转发给另一个连接的玩家~

内容的提问来源于stack exchange,提问作者Joy Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 08:42:32