4、第一个OPC UA客户端:创建客户端实例、连接服务器、断开连接、异常处理、连接状态监控
好,咱们今天来写第一个OPC UA客户端程序。
说实话,很多新手一上来就想着读写变量、订阅数据,结果连服务器都连不上,卡在那半天。我刚开始做OPC UA开发时也犯过这毛病——代码写了一大堆,一运行就报错,最后发现是连接参数写错了。所以这节课,咱们先把基本功打扎实。
4.1 创建客户端实例
在OPC UA的世界里,客户端就是一个Client对象。用Python的opcua库,创建实例其实就一行代码的事。
from opcua import Client
# 创建客户端实例
client = Client("opc.tcp://localhost:4840")
嗯,就这么简单。但这里有个坑——URL的格式必须写对。OPC UA的地址是opc.tcp://开头的,不是http://。我见过有人把地址写成http://localhost:4840,然后跑来问我为什么连不上……
4.2 连接服务器
创建完客户端实例,下一步就是连接服务器。调用connect()方法就行。
try:
client.connect()
print("连接成功!")
except Exception as e:
print(f"连接失败:{e}")
这里我建议你一定要加try-except。为什么?因为网络连接这东西,谁也说不准。服务器可能没启动,防火墙可能挡着,或者地址写错了。不加异常处理,程序一崩你就傻眼了。
我在项目中遇到过最离谱的一次——客户说服务器地址没问题,我连了半小时都连不上。最后发现是服务器端的证书过期了。嗯,这种问题靠try-except就能捕获到错误信息,省得你瞎猜。
4.3 断开连接
用完客户端,记得断开连接。这就像出门要锁门一样,是个好习惯。
client.disconnect()
print("已断开连接")
有些人觉得断开连接无所谓,反正程序结束了连接自然就断了。但你想过没有?如果程序异常退出了,服务器那边可能还挂着你的会话,占着资源不释放。时间长了,服务器性能就下来了。
with语句来自动管理连接,这样就不用担心忘记断开了。
with Client("opc.tcp://localhost:4840") as client:
client.connect()
# 在这里做你的操作
# 退出with块时自动断开
4.4 异常处理
OPC UA通信中,异常处理是重中之重。常见的异常有:
| 异常类型 | 说明 | 常见原因 |
|---|---|---|
ua.UaStatusCodeError |
OPC UA状态码错误 | 服务器返回了错误状态 |
ConnectionError |
连接错误 | 网络不通、服务器未启动 |
TimeoutError |
超时错误 | 网络延迟高、服务器响应慢 |
AttributeError |
属性错误 | 访问了不存在的节点 |
我曾经在一个项目中,因为没处理UaStatusCodeError,程序跑了三天突然崩溃了。排查了半天,发现是服务器重启后,客户端还在用旧的会话ID去访问数据。从那以后,我写OPC UA代码都会加上全面的异常处理。
try:
client.connect()
# 业务逻辑
except ua.UaStatusCodeError as e:
print(f"OPC UA错误:{e}")
except ConnectionError as e:
print(f"连接错误:{e}")
except TimeoutError as e:
print(f"超时:{e}")
except Exception as e:
print(f"未知错误:{e}")
finally:
client.disconnect()
4.5 连接状态监控
连接上了,不代表一直连着。网络波动、服务器重启、防火墙超时……这些都可能让连接断开。所以,监控连接状态很重要。
opcua库提供了get_connection_state()方法,可以获取当前连接状态。
state = client.get_connection_state()
print(f"当前连接状态:{state}")
状态值一般有:
closed:已断开connecting:正在连接connected:已连接disconnecting:正在断开
但说实话,光靠手动查状态不够实时。我一般会开一个后台线程,定期检查连接状态。如果发现断了,就自动重连。
import threading
import time
def monitor_connection(client):
while True:
state = client.get_connection_state()
if state != "connected":
print("连接断开,尝试重连...")
try:
client.connect()
print("重连成功!")
except:
print("重连失败,5秒后重试...")
time.sleep(5)
# 启动监控线程
monitor_thread = threading.Thread(target=monitor_connection, args=(client,))
monitor_thread.daemon = True
monitor_thread.start()
- 创建客户端实例时,URL格式必须正确
- 连接和断开都要加异常处理
- 用
with语句可以自动管理连接 - 连接状态监控建议用后台线程实现
- 重连机制是生产环境的必备功能
好了,这就是第一个OPC UA客户端的基本操作。说白了就是三步:创建、连接、断开。但每一步都有它的门道。你想想看,如果连这些都搞不清楚,后面那些读写变量、订阅数据的功能,能跑得起来吗?
下一节课,咱们会深入讲讲如何浏览服务器上的节点结构。到时候你会发现,OPC UA的世界其实挺有意思的。