open62541(opcua)传输延迟探索小记
缘起
将open62541作为中间件使用代替自定义数据的RPC,client通过订阅valueChange来接收数据。使用时发现有一些问题:
- 前后两次产生的数据相同时,不会触发valueChange
- 如果数据更新较快,client会漏掉其中一些数据
探索
问题1:
其实不是问题,这是opcua的属性,valueChange是根据采样(sample)来生成的,并不是server执行了writeValue就会触发事件。只能说这种模式不适合这种每次server产生结果都需要client响应的需求。(有一个小问题,是如何快速判断数值变化的?基本类型可以判断是否和原始数据不相等,对于复杂数据,如图片,逐字节比对?)
问题2:
还是和采样模式相关,如果在两次采样之间数据多次变化是没办法感知的。那就修改采样频率:采样频率同时受server和client的影响,server决定范围,client在范围内决定最终结果。如果client设定为0,则采用server能实现的最快频率。
心生一计
改进方式是将结果通过event发送,设置为report模式。数据内容自己填充,相同的数据也不会被过滤掉;主动report,脱离采样的限制(但响应时间还是受publish间隔的约束)。
event一般是简单消息的通知,承载传递数据的用法不算主流,或许能说明opcua的灵活性吧,不知道这是否存在潜在缺陷。这种模式和pub-sub很类似,不同点在于pub-sub利用的是udp的多播,event还是在server-client的形态下。pub-sub就是为实时性的需求设计的(类似dds),如果只是发送数据,pub-sub会更适合。
使用event基本能满足需求,但是响应的速度还是不够快。网络上查询说是opcua实时性只能到100ms左右,对于目前应用来说,时间上达不到要求。实际测试发现,publish间隔是关键因素,和sample一样,server决定范围,client决定最终结果。将publish间隔设置到1ms,从server发送event到client接收的延迟终于能达标。官方建议不能低于5ms,但测试设置到0也没什么副作用,一开始考虑可能会cpu空转高占用,但并没有。
小插曲
在测试过程中发现在windows平台下,当publish间隔设置为1ms时,本地回环网络还是会有16ms左右的延迟,相同代码在ubuntu下延迟可以稳定在1ms以内。一度为此纠结了很久,一度想换pub-sub甚至dds。后来用asio进行单纯的tcp数据传输测试发现也会有相同的延迟,才确认这是平台的原因(电脑个体差异,待验证?)。Windows下的网络效率不如linux有耳闻,但差距有这么大吗?
补充
在使用qtopcua作为client的过程中,设置相同的参数(publish间隔通过QOpcUaMonitoringParameters设置),还是会有50-60ms的延迟。网上遍寻无果,官方文档不够详细(qtopcua只包含在收费嵌入式的开发套件中,不知道交钱的文档有没有详细些)。最后无奈啃起qtopcua的源码,收获如下:opcua client执行迭代(UA_Client_run_iterate)才会响应event,qt是一个异步的库,qtopcua通过定时器来执行迭代,默认的超时时间就是50ms。通过QOpcUaProvider创建QOpcUaClient时,将超时时间设置放在backendProperties。正确的设置方式如下:
auto client = QOpcUaProvider::createClient("open62541", QVariantMap({"clientIterateIntervalMs", 1}));
server设置sample和publish的间隔范围方式如下:
auto config = UA_Server_getConfig(server);
config->publishingIntervalLimits = UA_DurationRange{1.0, 24 * 60 * 60 * 1000};
config->samplingIntervalLimits = UA_DurationRange{1.0, 24 * 60 * 60 * 1000};
client设置publish间隔的方式如下:
auto request = UA_CreateSubscriptionRequest_default();
request.requestedPublishingInterval = 1.0;
open62541(opcua)传输延迟探索小记的更多相关文章
- JS原型探索小记(一)
最近,我学习了jquery的源码,有个很深的认识就是——当对js的基本语法和面向对象思维了解比较熟悉之后,js真正的精髓在通过阅读一些优秀的框架源码也显现出来,我个人总结为对原型(原型链)和闭包两个基 ...
- 【转】实习小记-python 内置函数__eq__函数引发的探索
[转]实习小记-python 内置函数__eq__函数引发的探索 乱写__eq__会发生啥?请看代码.. >>> class A: ... def __eq__(self, othe ...
- 实习小记-python 内置函数__eq__函数引发的探索
乱写__eq__会发生啥?请看代码.. >>> class A: ... def __eq__(self, other): # 不论发生什么,只要有==做比较,就返回True ... ...
- 基于open62541的opc ua 服务器开发实现(1)
关于opcua的介绍这里就不多说了,相信大家大都有了一些了解,open62541是一个开源C(C99)的opc-ua实现,开源代码可在官网或github上下载. 话不多说,首先搭建一个opcua服务器 ...
- python工业互联网监控项目实战5—Collector到opcua服务
本小节演示项目是如何从连接器到获取Tank4C9服务上的设备对象的值,并通过Connector服务的url返回给UI端请求的.另外,实际项目中考虑websocket中间可能因为网络通信等原因出现中断情 ...
- 【探索】机器指令翻译成 JavaScript
前言 前些时候研究脚本混淆时,打算先学一些「程序流程」相关的概念.为了不因太枯燥而放弃,决定想一个有趣的案例,可以边探索边学. 于是想了一个话题:尝试将机器指令 1:1 翻译 成 JavaScript ...
- 【探索】利用 canvas 实现数据压缩
前言 HTTP 支持 GZip 压缩,可节省不少传输资源.但遗憾的是,只有下载才有,上传并不支持.如果上传也能压缩,那就完美了.特别适合大量文本提交的场合,比如博客园,就是很好的例子. 虽然标准不支持 ...
- 探索C#之6.0语法糖剖析
阅读目录: 自动属性默认初始化 自动只读属性默认初始化 表达式为主体的函数 表达式为主体的属性(赋值) 静态类导入 Null条件运算符 字符串格式化 索引初始化 异常过滤器when catch和fin ...
- Mysql事务探索及其在Django中的实践(二)
继上一篇<Mysql事务探索及其在Django中的实践(一)>交代完问题的背景和Mysql事务基础后,这一篇主要想介绍一下事务在Django中的使用以及实际应用给我们带来的效率提升. 首先 ...
随机推荐
- ctf之SusCTF2017-Crack Zip
题目信息如下,可知为杂项题,且无提示 下载文件打开如图,该压缩包是加密的 首先想到的是暴力破解,下载zip暴力破解软件打开文件. 下一步,选择暴力破解 进行暴力破解设定,进行破解 破解完成,得到密解压 ...
- c语言:2.3.3
#include <stdio.h> //赋值时类型原则:赋值号右边表达式值 变量 常量的类型最好与左边变量的类型相一致 //二者不相同时,C编译系统会自动实现数据类型转换 //转换原则: ...
- 【译】.NET 对象分配工具
随着 Visual Studio 16.10 的发布,性能分析器又有了一个新的分析引擎,.NET 对象分配工具是第一个加入的工具.这为该工具提供了一些新特性,并显著提高了 perf 性能.在你的 C# ...
- MySQL8.0.26安装与卸载
一.安装 1.官网下载 百度进入官网,学习用社区版够了,我下的是压缩版点这直达下载页 据说8.X版本性能优化,比5.7版本快2倍! 接着,不登录直接下载 2.创建配置 下载完后,建议解压到一个没有中文 ...
- [JS]闭包和词法环境
词法环境 词法环境(lexical environment)由两个部分组成: 环境记录--一个存储所有局部变量作为其属性的对象. 对外部词法环境的引用,与外部代码相关联. 全局词法环境在脚本执行前创建 ...
- sqldbx配置连接Oracle 12C数据库
本地开发环境: Windows10 64位.Oracle 12C客户端 32位.sqlDBX (32位) =============================================== ...
- 第二十五篇 -- QTreeWidget右击菜单的实现
效果图: 自己画一个ui,如图,前面已经讲过怎么用Qt Designer画图了,现在就不赘述了. ui_play.py # -*- coding: utf-8 -*- # Form implement ...
- 斐波那契数列——Python实现
# 功能:求斐波那契数列第 n 个数的值 # 在此设置 n n = 30 print('\n');print('n = ',n) # 代码生成 Fibonacci 序列,存于数组A A = [0] ...
- K-Fold 交叉验证
转载--原文地址 www.likecs.com 1.K-Fold 交叉验证概念 在机器学习建模过程中,通行的做法通常是将数据分为训练集和测试集.测试集是与训练独立的数据,完全不参与训练,用于最终模型的 ...
- 计算距离2020年圣诞节还有x天x时x分x秒
//计算两者相差毫秒数 //创建当前时间和圣诞节时间的Date对象 var d1=new Date(); var d2=new Date('2020/12/25'); //计算相差的毫秒 var d= ...