下载
https://github.com/open62541/open62541/releases/tag/v1.4.6
安装
解压后 创建bulid文件夹
进入bulid 打开终端
cmake ..
make
make install
安装到了 /usr/local
功能说明
该程序包含变量节点、对象节点、方法节点的创建及访问,服务器在多线程中运行,客户端有界面,可点击按钮查看打印信息进行测试。
编译之前 点掉对号
启动程序界面
此时服务器已自动启动,点击连接按钮后,客户端连接服务器成功,可点击其他按钮进行测试。
客户端工具 下载
https://pan.quark.cn/s/864a720f9d24
QT代码
pro
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
DESTDIR = $$PWD/bin
UI_DIR = $$PWD/UI
INCLUDEPATH += $$PWD/UI
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
opcserver.cpp \
widget.cpp
HEADERS += \
opcserver.h \
widget.h
FORMS += \
widget.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
unix:!macx: LIBS += -L/usr/local/lib/ -lopen62541
INCLUDEPATH += /usr/local/lib
DEPENDPATH += /usr/local/lib
unix:!macx: PRE_TARGETDEPS += /usr/local/lib/libopen62541.a
客户端核心代码
.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <open62541/client.h>
#include <open62541/client_config_default.h>
#include <open62541/client_highlevel.h>
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
void on_pushButton_4_clicked();
void on_pushButton_5_clicked();
private:
void seeNode(UA_NodeId nodeId);
private:
Ui::Widget *ui;
UA_Client *client = nullptr;
};
#endif // WIDGET_H
.cpp
#include "widget.h"
#include "ui_widget.h"
#include "opcserver.h"
#include <stdio.h>
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
opcServer *opcserver = new opcServer();
opcserver->start();
}
Widget::~Widget()
{
delete ui;
UA_Client_delete(client); /* Disconnects the client internally */
}
void Widget::on_pushButton_2_clicked()
{
/* Create a client and connect */
client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
UA_StatusCode status = UA_Client_connect(client, "opc.tcp://127.0.0.1:4841");
if(status != UA_STATUSCODE_GOOD) {
UA_Client_delete(client);
qDebug()<<"连接"<<"失败";
//return status;
}
else
{
qDebug()<<"连接"<<"成功";
}
}
void Widget::on_pushButton_clicked()
{
/* Read the value attribute of the node. UA_Client_readValueAttribute is a
* wrapper for the raw read service available as UA_Client_Service_read. */
UA_Variant value; /* Variants can hold scalar values and arrays of any type */
UA_Variant_init(&value);
UA_StatusCode status = UA_Client_readValueAttribute(client, UA_NODEID_STRING(1, "the.answer"), &value);
qDebug()<<"status"<<status;
if(status == UA_STATUSCODE_GOOD &&
UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_INT32])) {
qDebug()<<"the value is:"<<*(UA_Int32*)value.data;
}
else
{
qDebug()<<"UA_Client_readValueAttribute"<<"失败";
}
/* Clean up */
UA_Variant_clear(&value);
}
void Widget::on_pushButton_3_clicked()
{
UA_Variant value; /* Variants can hold scalar values and arrays of any type */
UA_Variant_init(&value);
UA_StatusCode status = UA_Client_readValueAttribute(client, UA_NODEID_NUMERIC(0, 50906), &value);
qDebug()<<"status"<<status;
if(status == UA_STATUSCODE_GOOD /*&&
UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_INT32])*/) {
qDebug()<<"the value is:"<<*(UA_Int32*)value.data;
}
else
{
qDebug()<<"UA_Client_readValueAttribute"<<"失败";
}
/* Clean up */
UA_Variant_clear(&value);
}
void Widget::on_pushButton_4_clicked()
{
/* Call a remote method */
UA_Variant input;
UA_String argString = UA_STRING("everyone");
UA_Variant_init(&input);
UA_Variant_setScalarCopy(&input, &argString, &UA_TYPES[UA_TYPES_STRING]);
/* Call a remote method */
UA_Variant input2;
UA_String argString2 = UA_STRING("everyone2");
UA_Variant_init(&input2);
UA_Variant_setScalarCopy(&input2, &argString2, &UA_TYPES[UA_TYPES_STRING]);
UA_Variant input_array[2] = {
input,input2};
size_t outputSize;
UA_Variant *output;
UA_StatusCode retval = UA_Client_call(client, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
UA_NODEID_NUMERIC(1, 62541), 2, input_array, &outputSize, &output);
if(retval == UA_STATUSCODE_GOOD)
{
qDebug()<< "Method call was successful, and %lu returned values available"<<(unsigned long)outputSize;
UA_String outString = *(UA_String*)output[0].data;
UA_String outString2 = *(UA_String*)output[1].data;
//UA_String outString = *(UA_String*)output->data;
qDebug()<< outString.length<<QByteArray((char*)outString.data);
qDebug()<< outString2.length<<QByteArray((char*