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

asyncua异步连接PLC端OPCUA服务器超时问题求助

异步OPC UA客户端连接超时(含CancelledError)问题排查

问题背景

在Windows 10 x64环境下使用asyncua库连接PLC部署的OPC UA服务器时,同步代码可正常建立连接,但异步代码调用await client.connect()会抛出包含asyncio.exceptions.CancelledError的TimeoutError。其他第三方OPC UA客户端均可正常连接该服务器,且异步代码中若不使用await调用节点方法,会返回协程对象而非预期的数值/布尔值。

同步正常连接代码

client = Client("opc.tcp://192.168.1.88:4840")
# client.max_chunkcount = 5000 # in case of refused connection by the server
# client.max_messagesize = 16777216 # in case of refused connection by the server
client.connect()

错误日志

disconnect_socket was called but connection is closed
close_session was called but connection is closed
close_secure_channel was called but connection is closed
disconnect_socket was called but connection is closed
Traceback (most recent call last):
  File "Python311\Lib\asyncio\tasks.py", line 490, in wait_for
    return fut.result()
           ^^^^^^^^^^^^
asyncio.exceptions.CancelledError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "OPCgpt.py", line 28, in <module>
    loop.run_until_complete(connect_to_opc_server())
  File "Python311\Lib\asyncio\base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "OPCgpt.py", line 12, in connect_to_opc_server
    await client.connect()
  File "Python311\Lib\site-packages\asyncua\client\client.py", line 287, in connect
    await self.open_secure_channel()
  File "Python311\Lib\site-packages\asyncua\client\client.py", line 374, in open_secure_channel
    result = await self.uaclient.open_secure_channel(params)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "Python311\Lib\site-packages\asyncua\client\ua_client.py", line 315, in open_secure_channel
    return await self.protocol.open_secure_channel(params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "Python311\Lib\site-packages\asyncua\client\ua_client.py", line 232, in open_secure_channel
    await asyncio.wait_for(self._send_request(request, message_type=ua.MessageType.SecureOpen), self.timeout)
  File "Python311\Lib\asyncio\tasks.py", line 492, in wait_for
    raise exceptions.TimeoutError() from exc
TimeoutError

复现代码

import asyncio
from asyncua import Client

async def connect_to_opc_server():
    # 创建OPC UA客户端
    client = Client(url="opc.tcp://192.168.1.88:4840")
    # client.max_chunkcount = 5000
    # client.max_messagesize = 16777216
    client.name = "Re_Shoes"

    try:
        # 连接OPC UA服务器
        await client.connect()

        # 列出根节点的所有子节点
        root_node = await client.get_root_node()
        print("root node is: ", root_node)

    finally:
        # 断开与服务器的连接
        await client.disconnect()

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(connect_to_opc_server())
    loop.close()

可能原因及解决方案

1. 异步客户端超时设置过短

asyncua异步客户端默认超时时间可能不足以应对PLC服务器的响应延迟,手动增加超时时间:

client = Client(url="opc.tcp://192.168.1.88:4840")
client.timeout = 30  # 调整为30秒,根据实际网络情况修改

2. Windows异步事件循环兼容性问题

Windows 10默认的asyncio事件循环在部分场景下存在兼容性问题,改用ProactorEventLoop:

if __name__ == "__main__":
    asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
    loop = asyncio.get_event_loop()
    loop.run_until_complete(connect_to_opc_server())
    loop.close()

3. 未同步设置连接参数

同步代码中注释的max_chunkcount和max_messagesize参数可能是连接PLC服务器的必要配置,取消注释并启用:

client.max_chunkcount = 5000
client.max_messagesize = 16777216

4. 服务器对异步请求的特殊限制

部分PLC的OPC UA服务器对异步请求的处理逻辑与同步不同,启用调试日志查看详细交互过程:

import logging
logging.basicConfig(level=logging.DEBUG)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 13:05:17