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中的使用以及实际应用给我们带来的效率提升. 首先 ...
随机推荐
- Git的安装和配置 -入门
Git的版本有很多种,适应各种windows,IOS, Linux平台的安装. 我用的是linux Centos7的版本: 1. 安装命令用Yum, 非常简单就可以安装完毕. yum install ...
- IE浏览器查看星号密码
用CHROME打开保存密码的网页,F12,右击"密码框"检查,编辑属性:password改为passw(只要不是password即可)即可显示密码
- DEV-C++ 5.11调试设置方法
DEV-C++调试设置方法:默认不能调试,打开调试的方法: 1.点击"工具"菜单--编译选项--"代码生成/优化"--连接器--"产生调试信息&quo ...
- css列表属性和样式控制
如下图是360浏览器主页的内容,上边有导航,下边是新闻列表,这种布局很常见,今天就来学习css列表属性之后并制作它. 列表属性 html有三种类型的列表:无序列表,有序列表和自定义列表.设置列表标记有 ...
- tomcat隐藏版本信息防止人为扫描特定版本漏洞攻击服务器
1.进入tomcat的lib目录找到catalina.jar文件 cd /dir/apache-tomcat-10.0.2/lib/ 2.解压文件 unzip catalina.jar 进入org/a ...
- 雪花算法(SnowFlake)Java实现
分布式id生成算法的有很多种,Twitter的SnowFlake就是其中经典的一种. 算法原理 SnowFlake算法生成id的结果是一个64bit大小的整数,它的结构如下图: 1bit,不用,因为二 ...
- Day6 三种结构 顺序选择循环!
顺序结构 从上到下依次执行,它是任何算法都离不开的一种基本算法结构. package com.xiaoming.struct;public class ShunXuDemo { public ...
- React中组件之间通信的方式
一.是什么 我们将组件间通信可以拆分为两个词: 组件 通信 回顾Vue系列的文章,组件是vue中最强大的功能之一,同样组件化是React的核心思想 相比vue,React的组件更加灵活和多样,按照不同 ...
- 给你的Mac 整个好用的命令行iTerm2 + zsh + oh-my-zsh + powerlevel10k
给你的Mac 整个好用的命令行iTerm2 + zsh + oh-my-zsh + powerlevel10k 介绍 iTerm2 是一个MacOS 下的终端模拟器,和其他的终端本质上没啥大不同.但相 ...
- CentOS下配置Nginx实现动静分离实例
测试环境: CentOS Linux release 7.6 PHP 7.2.32 两台服务器:192.168.1.109(Nginx),192.168.1.118(Apache) 1. 安装配置19 ...