Qt+OPC開發筆記(三):OPC客戶端訂閱特點消息的Demo

若該文為原創文章,轉載請注明原文出處
本文章博客地址:https://hpzwl.blog.csdn.net/article/details/148868209

長沙紅胖子Qt(長沙創微智科)博文大全:開發技術集合(包含Qt實用技術、樹莓派、三維、OpenCV、OpenGL、ffmpeg、OSG、單片機、軟硬結合等等)持續更新中…

Qt開發專欄:三方庫開發技術

上一篇:《Qt+OPC開發筆記(二):OPC客戶端介紹與讀取和寫入bool類型Demo》
下一篇:敬請期待…


前言

??本篇介紹opc客戶端訂閱消息,實現一個opc事件的訂閱,當訂閱的數據在服務器發生變化是,客戶端能立即得到更新。


Demo

??請添加圖片描述


OPC客戶端

??OPC 客戶端是一種利用OPC(OLE for Process Control)協議與 OPC 服務器進行通信的軟件應用程序。

功能特點

  • 數據訪問:提供一套簡單易用的 API,使開發人員能輕松地創建、讀取、更新和刪除OPC服務器上的數據項,可從傳感器、PLC、DCS 系統、過程分析儀等各種數據源獲取實時數據。
  • 事件訂閱(當前使用):支持實時數據變化訂閱,當服務器端的數據發生變化時,客戶端能夠立即獲取到更新,以便及時響應和處理數據變化。
  • 連接管理:負責建立和管理與 OPC 服務器的連接,包括連接的建立、監控連接狀態以及在發生異常時進行重連或斷開。
  • 數據展示與處理:允許用戶創建和管理數據視圖,通常以表格或圖形的方式展示實時數據流,還能對采集到的數據進行分析、存儲、歸檔等處理,為決策提供支持。

數據訪問方式

??OPC 協議支持多種數據訪問方式,以滿足不同的應用場景需求:

  • 同步訪問:客戶端發送請求后會一直等待,直到服務器返回響應。這種方式適用于對實時性要求較高的場景,但如果服務器響應時間較長,可能會導致客戶端程序阻塞。
  • 異步訪問:客戶端發送請求后不會等待服務器響應,而是繼續執行后續操作。當服務器處理完請求后,會通過回調函數通知客戶端。這種方式可以提高客戶端程序的效率,避免阻塞。
  • 訂閱訪問(當前使用):客戶端可以訂閱特定的數據項,當這些數據項的值發生變化時,服務器會主動將更新后的數據推送給客戶端。這種方式適用于需要實時監控數據變化的場景。

訂閱服務器某個消息

步驟一:連接服務器

??在這里插入圖片描述

步驟二:創建訂閱

??在這里插入圖片描述

??在這里插入圖片描述

步驟三:創建監聽項

??在這里插入圖片描述

步驟四:處理回調函數

??這里是通過subId與監控id對應來確定是哪一個變量變化。
??在這里插入圖片描述

步驟五:Qt兼容使用定時器定時調用

??在這里插入圖片描述


Demo關鍵源碼

創建訂閱和監控項

bool OpcClientManager::createSubscriptionResponse()
{/*OPC UA中的訂閱是異步的。也就是說,客戶端向服務器發送多個PublishRequest。服務器返回帶有通知的PublishResponses。但只有在生成通知時。客戶端不會等待響應,而是繼續正常操作。請注意訂閱和受監視項目之間的區別。訂閱用于報告通知。MonitoredItems用于生成通知。每個MonitoredItem只附加到一個訂閱。訂閱可以包含許多受監視的項目。客戶端在后臺自動處理PublishResponses(帶回調),并在傳輸中保留足夠的PublishRequests。ublishResponses可以在同步服務調用期間或在“UA_Client_run_iterate”中接收*/// 步驟一:創建一個默認的訂閱請求對象(有訂閱再開放)_subscriptionRequest = UA_CreateSubscriptionRequest_default();_subscriptionRequest.requestedPublishingInterval = 1000; // 設置發布間隔為1000毫秒,即每秒發布一次數據_subscriptionRequest.requestedLifetimeCount = 300;       // 設置生命周期計數為300,即服務器在300個發布周期后會終止該訂閱_subscriptionRequest.requestedMaxKeepAliveCount = 10;    // 設置最大保持活動計數為10,即服務器在10個發布周期內沒有數據變化時,仍會發送空的通知以保持連接活躍_subscriptionRequest.maxNotificationsPerPublish = 0;     // 設置每個發布周期的最大通知數為0,表示不限制通知數量_subscriptionRequest.publishingEnabled = true;           // 啟用發布功能,允許服務器主動推送數據_subscriptionRequest.priority = 0;                       // 設置訂閱的優先級為0,數值越高優先級越高// 步驟二:設置訂閱回復,設置狀態改變通知回調和刪除訂閱回調_subscriptionResponse = UA_Client_Subscriptions_create(_pUAClient,_subscriptionRequest,NULL,OpcClientManager::statusChangeNotificationCallback,OpcClientManager::deleteSubscriptionCallback);if(_subscriptionResponse.responseHeader.serviceResult != UA_STATUSCODE_GOOD){LOG << QString("Failed to UA_Client_Subscriptions_create, error code: 0x%1").arg(UA_StatusCode_name(_subscriptionResponse.responseHeader.serviceResult));return false;}LOG << "Succeed to UA_Client_Subscriptions_create, id:" << _subscriptionResponse.subscriptionId;startTimer(100);return true;
}bool OpcClientManager::createMonitoredItemRequest(int ns, int i)
{// 前置:有一個訂閱實例// 步驟三:創建監控項請求,需要傳入監控的節點LOG << ns << i;UA_NodeId nodeId = UA_NODEID_NUMERIC(ns, i);UA_MonitoredItemCreateRequest monitoredItemCreateRequest = UA_MonitoredItemCreateRequest_default(nodeId);monitoredItemCreateRequest.requestedParameters.samplingInterval = 100;  // 采樣間隔(單位:毫秒),指定服務器多久讀取一次被監控變量的實際值。monitoredItemCreateRequest.requestedParameters.discardOldest = true;    // 當監控項的隊列(Queue)已滿時,是否丟棄最早的數據。monitoredItemCreateRequest.requestedParameters.queueSize = 10;          // 服務器為該監控項保留的歷史值隊列大小。queueSize = 10 表示服務器最多保存10個未發送給客戶端的值// 添加監控項到訂閱UA_MonitoredItemCreateResult monResult = UA_Client_MonitoredItems_createDataChange(_pUAClient,_subscriptionResponse.subscriptionId,UA_TIMESTAMPSTORETURN_BOTH,monitoredItemCreateRequest,NULL,OpcClientManager::dataChangeNotificationCallback,NULL);if(monResult.statusCode != UA_STATUSCODE_GOOD){LOG << "監控項創建失敗 error:" << QString(UA_StatusCode_name(monResult.statusCode));return false;}else{LOG << "成功監控節點 MonId: " << monResult.monitoredItemId;return true;}}

回調函數

void OpcClientManager::statusChangeNotificationCallback(UA_Client *client, UA_UInt32 subId, void *subContext, UA_StatusChangeNotification *notification)
{LOG << __FUNCTION__ << client << subId;
}void OpcClientManager::deleteSubscriptionCallback(UA_Client *client, UA_UInt32 subId, void *subContext)
{LOG << __FUNCTION__ << client << subId;
}void OpcClientManager::dataChangeNotificationCallback(UA_Client *client, UA_UInt32 subId, void *subContext, UA_UInt32 monId, void *monContext, UA_DataValue *value)
{LOG << __FUNCTION__ << client << subId;LOG << "數據變化通知 - 監控項ID: " << monId;if(value->hasValue && value->value.type){UA_Variant *var = &value->value;if(var->type == &UA_TYPES[UA_TYPES_BOOLEAN]){LOG << *static_cast<bool *>(var->data);}else{LOG << "other types";}}
}

定時器處理

void OpcClientManager::timerEvent(QTimerEvent *event)
{if(_pUAClient){UA_Client_run_iterate(_pUAClient, 100);}
}

工程模板v1.2.0

??在這里插入圖片描述


入坑

入坑一:訂閱變量后未通知

問題

??訂閱變量后未通知
??在這里插入圖片描述

嘗試

??檢查代碼沒有發現任何問題,考慮是否有其他問題。
??更換第三方單文件全代碼訂閱后,變化 也無通知:
??在這里插入圖片描述

??使用uaexpert測試,訂閱看起來是成了:
??在這里插入圖片描述

??修改成5秒,發現就是5秒了,所以這里訂閱是成功了。
??繼續考慮代碼問題了,再次查看,發現可能是打印緩存的問題,Qt輸出printf需要設置stdout為0:
??在這里插入圖片描述

??那么這個代碼是沒問題的。
??回到封裝的代碼,對比檢查,發下關鍵性代碼:
??在這里插入圖片描述

??在這里插入圖片描述

??所以open ua這個代碼,收到訂閱通知需要跑這個循環才可以收到。
在OPC UA通信中,客戶端需要持續運行并處理服務器推送的通知,而UA_Client_run_iterate函數正是用于實現這一點的關鍵機制。
??然后查看了其他一邊監聽一邊寫入的代碼,跟想象中一樣,間隔寫入(PS:就是單片機的單路徑一樣)
??在這里插入圖片描述

解決

??本意是用Qt的消息循環替代:
??在這里插入圖片描述
??這個靠Qt循環的不是那么準確,還需要完善這個流程,有可能處理會有2次一同處理。


上一篇:《Qt+OPC開發筆記(二):OPC客戶端介紹與讀取和寫入bool類型Demo》
下一篇:敬請期待…


本文章博客地址:https://hpzwl.blog.csdn.net/article/details/148868209

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/86086.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/86086.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/86086.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

嵌入式開發學習日志Day8(ARM體系架構——按鍵、蜂鳴器及中斷)

一、蜂鳴器學習 代碼實現&#xff1a; 二、BSP工程管理及Makefile 1、BSP工程管理 利用BSP工程管理&#xff0c;使文檔顯示不雜亂&#xff1b; 將這些文件分為4類&#xff0c;并保存到4個不同的文件夾里。 首先在新的工程文件夾里創建一個之后我們編寫的類似led驅動&#xff0…

Linux部署Sonic前后端(詳細版)(騰訊云)

系統用的是Ubuntu 22.04 LTS 1、安裝Docker sudo apt update sudo apt install -y docker.io docker-compose sudo systemctl start docker sudo systemctl enable docker# 如果不想每次用 sudo&#xff0c;可以加權限 sudo usermod -aG docker $USER 2、安裝 docker-compose…

騰訊云CBS:企業級云存儲的性能與可靠性重構

摘要 根據Forrester 2025年網絡分析與可見性&#xff08;NAV&#xff09;報告&#xff0c;東西向流量安全與加密威脅檢測成為企業核心痛點&#xff08;誤報率降低需求↑40%&#xff09;。騰訊云CBS作為底層存儲支柱&#xff0c;通過三副本跨可用區冗余架構與毫秒級故障切換能力…

ubuntu 22.04 更換阿里源 (wsl2 參照)

步驟 1: 備份當前源列表 sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak 步驟 2: 編輯源列表文件 sudo nano /etc/apt/sources.list 步驟 3: 添加阿里云鏡像源 ubuntu 阿里源地址可以在這查看 ubuntu鏡像_ubuntu下載地址_ubuntu安裝教程-阿里巴巴開源鏡像站 …

idea中push拒絕,merge,rebase的區別

在 IntelliJ IDEA 中進行 Git 操作時&#xff0c;Push 拒絕&#xff08;Push Rejected&#xff09;、Merge 和 Rebase 是常見的沖突解決方式。它們有不同的適用場景和影響&#xff0c;下面詳細說明它們的區別&#xff0c;并附上流程圖幫助理解。 1. Push 拒絕&#xff08;Push …

輕松實現PDF局部擦除的技術級解決方案

在處理PDF文檔時&#xff0c;我們常常會遇到這樣的場景&#xff1a;想要刪除某段文字、擦除一張圖片&#xff0c;或者對頁面內容進行局部調整。但很多編輯工具要么操作繁瑣&#xff0c;要么功能受限&#xff0c;甚至還需要付費解鎖核心功能。 這是一款輕便又實用的PDF編輯工具…

css color 十六進制顏色透明度

css color 十六進制顏色透明度 例&#xff1a;#FFFFFF ~~ #FFFFFF1A(10% ) 0% 為 FF10% 為 1A20% 為 3330% 為 4D40% 為 6650% 為 8060% 為 9970% 為 B380% 為 CC90% 為 E6100% 為 00

Git簡介和常用命令

Git簡介 Git是一款版本管理軟件&#xff0c;可以在任何時間點保存文件&#xff0c;也能夠恢復到以前任意時間點保存的文檔&#xff0c;Git作用簡單舉例來說就是&#xff0c;寫論文&#xff0c;有很多個版本&#xff0c;將原來的論文保存起來&#xff0c;新建一個副本&#xff…

Kafka 性能調優指南

文章目錄 概述操作系統層面調優文件系統優化內存管理磁盤 I/O 優化 JVM 調優堆內存設置GC 收集器選擇常見 GC 問題 Broker 端調優版本兼容性關鍵參數配置日志段大小調優設置原則推薦配置調優考慮因素監控命令 應用層調優客戶端復用資源管理多線程消費模式 性能指標調優吞吐量優…

佰力博科技與您探討低溫真空探針臺如何保養

低溫真空探針臺是一種用于在低溫或真空環境下進行電學性能測試的精密儀器&#xff0c;其保養和維護對于確保設備的穩定運行和延長使用壽命至關重要。 一、日常清潔與檢查 1、使用后應立即清潔探針臺&#xff0c;尤其是探針、接口和連接器&#xff0c;避免灰塵和雜質影響精度。…

MySQL:深入總結鎖機制

寫在前面 在 MySQL 數據庫中&#xff0c;鎖機制是保障并發控制和數據一致性的關鍵。合理運用鎖機制&#xff0c;能有效避免數據競爭&#xff0c;提升數據庫性能。接下來&#xff0c;我們就深入了解 MySQL 中的各類鎖。 博主總結&#xff08;注&#xff1a;針對總結的詳解補充在…

AI+OT安全,讓威脅情報實現主動防御

當前&#xff0c;網絡犯罪組織的運作模式正日趨“企業化”&#xff0c;給全球網絡安全帶來了嚴峻挑戰。企業以及各類組織機構有必要采用威脅情報驅動的防御體系&#xff08;Threat-Informed Defense, TID&#xff09;&#xff0c;將安全運營模式從被動響應徹底轉向基于威脅情報…

深度剖析:UDS上下行分離隧道如何繞過主流防火墻?

&#x1f525; 深度剖析&#xff1a;UDS上下行分離隧道如何繞過主流防火墻&#xff1f; &#x1f4ca; 系統架構圖 #mermaid-svg-lv5FKIvBMKPeTFuW {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-lv5FKIvBMKPeTFuW …

Vue 使用vue-cli

Vue 漸進式JavaScript 框架 基于Vue2的學習筆記 - 使用Vue-cli 筆記 目錄 使用vue-cli 創建項目 配置文件 啟動項目 入口文件 Index.html Main.js Eslint修復 第一種 第二種 第三種 更換為淘寶源 查看當前配置 配置淘寶源 驗證配置 總結 使用vue-cli 創建項目…

Sentinel實現原理

Sentinel 是阿里巴巴開源的分布式系統流量控制組件&#xff0c;主要用于服務保護&#xff0c;涵蓋流量控制、熔斷降級、系統負載保護等功能。 以下是 Sentinel 的實現原理&#xff0c;使用中文簡要說明&#xff1a; 1. 總體架構 Sentinel 采用 輕量級 設計&#xff0c;分為 核…

DeepSeek生成HTML5生命天數計算器

DeepSeek生成HTML5生命天數計算器 讓DeepSeek生成一個生命天數計算器 提示詞prompt 幫我做一個我活了多少天的網頁 用戶輸入出生日期即可顯示我活了多少天 頁面ui要好看點&#xff0c;加上顯示官方統計 人一生平均可以活多少天 自動計算剩余天數。幫我按照上述需求再次生成一個…

如何使typora圖片不居中留白?

如何使typora圖片不居中留白&#xff1f; 駐波使用typora記筆記的時候&#xff0c;好幾次插入圖片太大選擇縮小都會發現圖片仍然滯留在中間&#xff0c;居中顯示&#xff0c;但我本人覺得并不好看&#xff0c;所以我決定改一下&#xff0c;于是有了這篇博客 檢查看原理 軟件內…

高精度頻率基石:超低相噪恒溫晶振的全場景應用解決方案

在科技高速發展的今天&#xff0c;頻率源作為電子系統的 “心臟”&#xff0c;其穩定性與可靠性直接決定著通信、導航、測量等關鍵領域的性能上限。深度洞察行業需求&#xff0c;重磅推出SYN3627L 型 100MHz 恒溫晶振&#xff08;OCXO&#xff09;。這款集高穩定性、低相位噪聲…

【android bluetooth 協議分析 01】【HCI 層介紹 27】【LeReadRemoteFeatures命令介紹】

深入理解 LE Read Remote Features 命令與事件響應 在藍牙低功耗&#xff08;BLE&#xff09;通信中&#xff0c;設備特性&#xff08;LE Features&#xff09;協商是連接過程中的一個關鍵環節。本文將詳細介紹 HCI 層的命令 LE_Read_Remote_Features 及其對應的事件響應 LE_R…

企業架構設計中的CBAM方法深度解析:成本效益驅動的架構決策藝術

目錄 CBAM方法概述與核心價值 CBAM核心流程與實施步驟 前期準備與場景確定 成本效益建模與分析 風險調整與決策制定 實施技巧與挑戰克服 CBAM實戰案例與應用場景 案例一&#xff1a;電商平臺促銷系統架構選型 案例二&#xff1a;制造業ERP系統云遷移決策 案例三&…