缘起

将open62541作为中间件使用代替自定义数据的RPC,client通过订阅valueChange来接收数据。使用时发现有一些问题:

  1. 前后两次产生的数据相同时,不会触发valueChange
  2. 如果数据更新较快,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)传输延迟探索小记的更多相关文章

  1. JS原型探索小记(一)

    最近,我学习了jquery的源码,有个很深的认识就是——当对js的基本语法和面向对象思维了解比较熟悉之后,js真正的精髓在通过阅读一些优秀的框架源码也显现出来,我个人总结为对原型(原型链)和闭包两个基 ...

  2. 【转】实习小记-python 内置函数__eq__函数引发的探索

    [转]实习小记-python 内置函数__eq__函数引发的探索 乱写__eq__会发生啥?请看代码.. >>> class A: ... def __eq__(self, othe ...

  3. 实习小记-python 内置函数__eq__函数引发的探索

    乱写__eq__会发生啥?请看代码.. >>> class A: ... def __eq__(self, other): # 不论发生什么,只要有==做比较,就返回True ... ...

  4. 基于open62541的opc ua 服务器开发实现(1)

    关于opcua的介绍这里就不多说了,相信大家大都有了一些了解,open62541是一个开源C(C99)的opc-ua实现,开源代码可在官网或github上下载. 话不多说,首先搭建一个opcua服务器 ...

  5. python工业互联网监控项目实战5—Collector到opcua服务

    本小节演示项目是如何从连接器到获取Tank4C9服务上的设备对象的值,并通过Connector服务的url返回给UI端请求的.另外,实际项目中考虑websocket中间可能因为网络通信等原因出现中断情 ...

  6. 【探索】机器指令翻译成 JavaScript

    前言 前些时候研究脚本混淆时,打算先学一些「程序流程」相关的概念.为了不因太枯燥而放弃,决定想一个有趣的案例,可以边探索边学. 于是想了一个话题:尝试将机器指令 1:1 翻译 成 JavaScript ...

  7. 【探索】利用 canvas 实现数据压缩

    前言 HTTP 支持 GZip 压缩,可节省不少传输资源.但遗憾的是,只有下载才有,上传并不支持.如果上传也能压缩,那就完美了.特别适合大量文本提交的场合,比如博客园,就是很好的例子. 虽然标准不支持 ...

  8. 探索C#之6.0语法糖剖析

    阅读目录: 自动属性默认初始化 自动只读属性默认初始化 表达式为主体的函数 表达式为主体的属性(赋值) 静态类导入 Null条件运算符 字符串格式化 索引初始化 异常过滤器when catch和fin ...

  9. Mysql事务探索及其在Django中的实践(二)

    继上一篇<Mysql事务探索及其在Django中的实践(一)>交代完问题的背景和Mysql事务基础后,这一篇主要想介绍一下事务在Django中的使用以及实际应用给我们带来的效率提升. 首先 ...

随机推荐

  1. 「CF527E」 Data Center Drama

    「CF527E」 Data Center Drama 传送门 显然一个环肯定满足题目条件. 然后我就开始想:先整一棵 \(\texttt{DFS}\) 树,然后非树边从深度深的节点向深度浅的节点连边, ...

  2. Spring Boot(一):如何使用Spring Boot搭建一个Web应用

    Spring Boot Spring Boot 是Spring团队旗下的一款Web 应用框架 其优势可以更快速的搭建一个Web应用 从根本上上来讲 Spring Boot并不是什么新的框架技术 而是在 ...

  3. python 读取 写入txt文件

    filename = 'pi_digits.txt' with open(filename) as f:#默认以只读方式打开文件 lines = f.readlines()#读取所有行,结果为列表,每 ...

  4. 【Java数据结构与算法】简单排序、二分查找和异或运算

    简单排序 选择排序 概念 首先,找到数组中最小的那个元素,其次,把它和数组的第一个元素交换位置(如果第一个元素就是最小的元素那么它就和自己交换).再次,在剩下的元素中找到最小的元素,将它与数组的第二个 ...

  5. 备战- Java虚拟机

    备战- Java虚拟机 试问岭南应不好,却道,此心安处是吾乡. 简介:备战- Java虚拟机 一.运行时数据区域 程序计算器.Java 虚拟机栈.本地方法栈.堆.方法区 在Java 运行环境参考链接: ...

  6. awk对某个字段分割处理

    工作中遇到要根据文件中某个字段分割成多行文本的处理,想到用awk处理,这里记录下: 问题: 原文件:假设一共2个字段,用"|"分割,其中第二个字段用"#"分割, ...

  7. Eclipse配置反编译插件jadclipse

    参考自:https://blog.csdn.net/moneyshi/article/details/79715891 Jad是一个Java的一个反编译工具,是用命令行执行,和通常JDK自带的java ...

  8. SpringBoot+Redis 实现消息订阅发布

    什么是 Redis Redis 是一个开源的使用 ANSI C语言编写的内存数据库,它以 key-value 键值对的形式存储数据,高性能,读取速度快,也提供了持久化存储机制. Redis 通常在项目 ...

  9. 记一次lombok踩坑记

    引言 今天中午正在带着耳机遨游在代码的世界里,被运营在群里@了,气冲冲的反问我最近有删生产的用户数据的吗?我肯定客气的回答道没有呀?生产的数据我怎么能随随便便可以删除,这可是公司的红线,再说了我也没有 ...

  10. DL基础补全计划(五)---数值稳定性及参数初始化(梯度消失、梯度爆炸)

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...