概述

为什么有这么多不同的协议/哪种物联网协议最快

历史上,评价秦始皇对中国最大的贡献,是“车同轨,书同文,统一度量衡”,因为基础设施有了统一的标准,促进了交通,文化,贸易的发展,方便了百姓生活。

万物联网,能不能来个万物统一的标准呢?从现状来看,答案是不能,就像编程语言,Java、C、Python、C++、C#、Go、JavaScript百花齐放,并不存在统一的语言,程序员最大的苦恼就是要学的编程语言太多了。

要学的编程语言太多了
要学的编程语言太多了

这时自然有人问了,最好的编程语言是哪种?“PHP是世界上最好的语言”是真的吗?对应到物联网协议中,就是哪种物联网协议速度最快?源码先生的观点是:

  • 首先要搞清楚如何对比,比如mqtt和5G就不能对比,mqtt是应用层协议,5G主要是物理层和数据链路层协议,对比mqtt和5G谁最速度最快,犹如对比奥特曼和孙悟空谁厉害一样,没有可比性;
  • 就像上百种编程语言,谁也不能完全替换谁,每种语言都有自己的优势和使用场景,也没有最快/最好的物联网协议,只有最合适的协议,业务场景不同,最合适的协议也不同。

万变不离其宗

虽然物联网协议很多,区别挺大,但本质还是可以追溯出来的,这就是OSI标准7层网络模型。


OSI标准7层网络模型

无论简单的串口通信,还是复杂的TCP/IP,无论低速的ZigBee,还是高速的5G,统统能套到OSI标准7层网络模型中,OSI模型就是万变不离其宗的宗。实际场景中,表示层和会话层一般也放到应用层,TCP/IP参考模型把OSI标准7层网络模型简化为5层模型。


TCP/IP参考模型

TCP/IP参考模型若能了然于胸,知其然,也能知其所以然的话,再多的物联网协议也不怕,真正做到妈妈再也不担心我的学习了。

为什么要分层/分层有什么用

要想搞清楚5层TCP/IP参考模型,第一步是搞清楚为什么要分层。遥想N多年前第一次接触TCP/IP参考模型时,源码先生是懵圈的,直接一把梭不香吗,只要能通信,何必搞这么复杂,分这么多层?


写程序一把梭

随着源码先生吃的饭越来越多,源码先生明白了,分层的道理和吃外卖是一样一样的。


外卖协议栈

对比TCP/IP参考模型和外卖协议栈,可以得出以下分层的优点。

流水线作业,各司其职

20世纪初,美国人亨利.福特首先采用了流水线生产方法,在他的工厂内,专业化分工非常细,仅一个生产单元的工序竟然多达7882种,为了提高工人的劳工效率,福特反复试验,确定了一条装配线上所需要的工人,以及每道工序之间的距离.这样里来,每个汽车底盘的装配时间从12小时28分缩短到1小时33分。

流水线作业中,分工明确,各司其职。对应到外卖协议栈中:

  • 大自然负责提供最宝贵却又免费的生长环境
  • 农民伯伯负责种植食材,但不用关心阳光和土壤从哪里来
  • 物流贸易商负责运输食材,但不用关心食材是如何种出来的
  • 饭店/厨师负责把食材做成饭,但不用关心食材从哪里来
  • 外卖小哥负责送外卖,但不用关心厨师如何做饭
  • 吃货负责吃,其他的一概不关心

对应到TCP/IP参考模型中:

  • 物理层对应物理传输介质,比如有线传输的双绞线,无线传输的电磁波
  • 数据链路层有了MAC地址,通过MAC寻址可以在多个设备之间传输数据,但不用关心通过有线传输还是无线传输
  • 网络层有了IP地址,通过IP寻址,可以在多个设备之间传输数据,但不用关心数据如何发送到目标MAC设备
  • 传输层有了端口,通过端口,同一个IP地址可以运行多个应用,多个应用的数据相互独立,但不用关心数据如何发送到目的IP设备
  • 应用层以HTTP为例,HTTP不用关心底层是TCP还是UDP,比如HTTP2之前的版本用的是TCP,到了HTTP3换成了UDP

可以看到,每层只需要调用下层服务,不需要关心服务如何实现,同时每层提供对外服务,供其他层调用。

灵活性好/维护性好

分层后,各层互不影响。当某一层发生变化时,只要其接口不变,其他层不受影响或者受影响程度很小,举个栗子:

  • 笔记本可以通过WIFI上网,也可以通过网线上网,对笔记本来说没有任何影响
  • 手机从3G到4G再到5G,速度提升了很多,对APP没有任何影响,即使将来6G和7G,APP也不受影响
  • IPv4更新为IPv6,对于浏览网页的应用层HTTP协议,影响并不大

分层后,可以分层调试协议,快捷方便,而且协议升级时,影响范围也不大。

分层的好处多多,不清楚分层有哪些优点时,只要往源码先生独创的外卖协议栈上套,想想吃货随意点外卖的惬意,就明白了。

如何快速入门一种协议

确定协议属于哪一层后,只关心本层协议即可,比如5G,更多的是如何优化物理层和数据链路层的无线传输,什么TCP、mqtt就不用关心了。源码先生整理了常见协议所属的分层:

模型 协议
物理层 有线传输如双绞线、同轴电缆、光纤等,无线传输如ZigBee、LoRa、2G、3G、4G、5G、NBIoT等
数据链路层 常见的有IEEE 802.11系列(如WIFI主要采用802.11b协议),IEEE 802.3(以太网),IEEE 802.15.1(蓝牙)、IEEE 802.15.4(ZigBee、6LoWPAN)等
网络层 常见的有IPv4、IPv6、6LoWPAN
传输层 常见的有TCP和UDP
应用层 常见的有HTTP、mqtt、COAP、OPC UA、ModBus、FTP等

很多协议是涉及多层的,比如LoRaWAN,包括从物理层到应用层5层全部网络模型。 |

弄清楚拓扑结构

两个设备相互通信,用一条线把两个设备连接起来即可。


网络拓扑结构

三个设备相互通信,两两相连需要3条线。


网络拓扑结构

四个设备相互通信,两两相连需要6条线。


网络拓扑结构

很明显,随着设备个数的增加,两两相连需要的线按指数级增长,所以两两相连的方式肯定是不合适了,总线型拓扑结构是一种简单的解决办法。


总线型网络拓扑结构

多个设备复用同一条总线,减少了布线的复杂度;其他网络拓扑结构有星型、环型、树型、总线型等多种,无论哪种网络拓扑结构,最终都是为了实现多个设备相互通信。

拓扑结构和5层TCP/IP参考模型并没有一一对应的关系,比如以太网是总线型拓扑结构,但是互联网(主要是TCP/IP)是混合型拓扑结构,由以太网+路由器+城域/省域/国域交换中心组成的混合拓扑结构;网络模型的每层都可以有自己的拓扑结构,比如mqtt是基于TCP/IP应用层协议(混合型拓扑结构),但是从应用层看,mqtt是星型拓扑结构。从整体上看,大多数协议都是混合型拓扑结构,只有细化到具体层时,才可以确定出具体的拓扑结构。弄清楚拓扑结构的目的,是为了从宏观上、整体上了解协议,只要达到了解协议的目的,并不需要严格的区分一个协议具体用到哪些拓扑结构。

拓扑结构中的冲突避免机制

总线上有多个设备,多个设备同时发送数据,数据会产生冲突,此时需要冲突避免机制,大部分冲突避免机制是在数据链路层实现,比如以太网使用的CSMA/CD(即载波侦听多路访问/冲突检测),但是也可以在应用层上实现冲突避免机制,如Modbus。

阅读标准文档

每个协议都有官方标准文档,这是最权威的协议资料,官方文档内容一般非常详细,适合深入研究协议。

一、物联网IoT协议之MQTT

为什么会写这篇mqtt教程

工作中经常用到各种开源的软件,比如docker,k8s,mongo,kafka等,也经常网上搜集各种学习资料,但是都没付过费,都是免费开源的,真要感谢丰富的开源世界,不然工作都没法进行了。时常想,老是白嫖可不行,也得分享点东西出来。最近工作中一直在用mqtt,于是准备写份mqtt教程,把学习到的mqtt知识分享出来。为了方便不同的读者,教程分为两大部分:

  • mqtt快速入门教程,快速了解如何使用mqtt,无须需要关心mqtt底层细节
  • mqtt完整教程,包括mqtt各种技术细节,适合mqtt进阶

物联网IoT协议之mqtt快速入门

什么是mqtt

mqtt是IBM 公司在1999年开发的即时通讯协议,它是一个轻量级的,基于发布/订阅模式的消息传输协议,专门为资源(如内存,网络等)受限的设备而设计,即使设备运行在低带宽、高延时、不稳定的网络中,通过mqtt依旧可以获得一定程度的、可靠的通信服务。

为什么物联网IoT需要mqtt

  • 物联网的首要任务是完成设备与设备的通信,而且不仅是一对一的通信,还包括多对多的通信,mqtt基于发布/订阅模式,原生支持多对多的通信,非常符合物联网的通信要求
  • mqtt是轻量级协议,相比HTTP,mqtt协议层占用的通信数据非常少,非常适合低带宽、资源受限的IoT设备
  • 无论是国外的AWS、Azure,还是国内的阿里云、腾讯云,都使用mqtt作为接入IoT设备的首选协议,mqtt已经成为物联网上云第一大协议

mqtt之Hello World

按照惯例,如果不懂mqtt,来个Hello World想必是极好的。mqtt是即时通信协议,和QQ/微信/手机短信非常像,这里就以小明和丽丽互发短信为例,作为mqtt的Hello World。开始Hello World前,需要先了解mqtt中的几个名词。

消息主题(topic)

可以类比为手机号,发短信前得先知道目标手机号,mqtt中发消息前得先知道目标topic。
topic是一个字符串,比如xiaoming,mqtt中常使用/作为分隔符,如/lanxiang/wajueji/xiaoming这样的格式,可以方便的看出这是蓝翔-挖掘机班-小明同学的topic。

消息发布(publish)

publish用来发布一条消息,伪代码为

publish('topic', 'payload')

其中topic为要发布消息的主题,payload为要发布消息的内容。

消息订阅(subscribe)

subscribe用来订阅一个消息主题,伪代码为

subscribe("topic")

其中topic为要订阅的消息的主题,订阅成功后,应用程序还需要注册一个回调函数,当有消息发送过来,回调函数会被调用,伪代码如

client.on("message", function (topic, payload) {
    alert([topic, payload].join(": "))
  })

其中on(“message”)为监控消息达到事件,function为回调函数,topic为收到的消息来自哪个主题,payload为收到消息的内容。

mqtt服务器(broker)

设备通过发布/订阅模式通信,设备需要先连接到mqtt服务器,多个设备之间的消息需要通过mqtt服务器中转,如下图


发布方(publisher)即发送消息的设备
订阅方(subscriber)即订阅消息的设备

mqtt服务器类似消息的中转站,所以mqtt服务器有一个更形象的名词,即消息代理服务器(Broker)。

客户端(client)

发布方和订阅方统称为客户端(client),一个设备可以即是发布方,也可以同时是订阅方,一个设备可以向多个topic发布消息,也可以订阅多个topic。

实现Hello World

下面我们完成小明和丽丽互发短信的示例。

选择一个在线mqtt服务器

首先我们要有一个mqtt服务器,由于mqtt只是一份标准规范,而目前符合mqtt标准的服务器已经有很多了,开源的有mosquitto,RabbitMQ,EMQ X Broker等。自己手动安装服务器,很容易出现选择困难症,到底哪家mqtt服务器强?其实最简单的方法,是直接使用网上公开的,在线mqtt服务器,mqtt官方公布了一个在线mqtt服务器列表,见在线mqtt服务器。这些线上服务器仅做测试使用,这里我们选取test.mosquitto.org作为Hello World的测试服务器。

选择一个mqtt客户端

mqtt客户端也有很多选择,经过源码先生的验证,开源的qmqtt-client使用比较简单,源码先生已经把qmqtt-client编译为exe,请直接下载吧。
双击qmqtt-client.exe,即可启动mqtt客户端。

小明和丽丽互发短信

启动一个mqtt客户端,代表小明,按照下图中的步骤连接mqtt服务器。

启动另一个mqtt客户端,代表丽丽,按照下图中的步骤连接mqtt服务器。

小明订阅消息主题/lanxiang/wajueji/xiaoming,类似小明给自己买了个手机号。

丽丽订阅消息主题/lanxiang/meirong/lili,类似丽丽给自己买了个手机号。

注意,不需要手动创建topic,第一次订阅或者第一次发布时服务器会自动创建topic

小明要给丽丽发信息,必须先知道丽丽的手机号,也不知道小明从哪里弄来了丽丽的手机号(/lanxiang/meirong/lili),总之,小明可以给丽丽发信息了。发信息的步骤如下图:

丽丽收到了新的消息,并回复了小明。

小明也收到了丽丽的回复。

小明心情不太好,此次mqtt通信到此结束。

linux版mqtt客户端

linux版mqtt客户端推荐mosquitto-clients,Ubuntu安装的mosquitto-clients的命令为

apt-add-repository ppa:mosquitto-dev/mosquitto-ppa
apt-get update
apt-get install mosquitto-clients

小明订阅消息的命令为:

mosquitto_sub -v -t '/lanxiang/wajueji/xiaoming' -h "test.mosquitto.org" -p 1883

丽丽订阅消息的命令为:

mosquitto_sub -v -t '/lanxiang/meirong/lili' -h "test.mosquitto.org" -p 1883

小明发布消息的命令为:

mosquitto_pub -h 'test.mosquitto.org' -p 1883 -t '/lanxiang/meirong/lili' -m '是丽丽吗,我是小明,在干嘛呢?'

丽丽发布消息的命令为:

mosquitto_pub -h 'test.mosquitto.org' -p 1883 -t '/lanxiang/wajueji/xiaoming' -m '准备睡了,有空再聊'

开发mqtt应用程序

开发mqtt的应用程序,需要使用mqtt客户端库,mqtt客户端库会提供publish、subscribe等API,应用程序调用客户端库的API即可完成mqtt通信。mqtt官方提供一个客户端库列表,见mqtt客户端库列表,其中Java,JavaScript,Python,go各种语言的mqtt客户端库应有尽有,请根据自己的口味自行选取。

C语言mqtt客户端示例

IoT设备端一般使用C语言开发,这里以Eclipse Paho Embedded C客户端库为例,发布方的示例代码为:

#include <stdio.h>
#include <memory.h>
#include "MQTTClient.h"

int main(int argc, char** argv)
{
    int rc = 0;
    unsigned char buf[100];
    unsigned char readbuf[100];

    Network n;
    MQTTClient c;

    NetworkInit(&n);
    NetworkConnect(&n, "test.mosquitto.org", 1883);
    MQTTClientInit(&c, &n, 1000, buf, 100, readbuf, 100);

    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;       
    data.willFlag = 0;
    data.MQTTVersion = 3;
    data.clientID.cstring = "xiaoming";

    data.keepAliveInterval = 10;
    data.cleansession = 1;

    // 连接mqtt服务器
    rc = MQTTConnect(&c, &data);
    printf("Connected %d\n", rc);

    // 发布消息
    MQTTMessage pubmsg;
    memset(&pubmsg, '\0', sizeof(pubmsg));
    pubmsg.payload = "是丽丽吗";
    pubmsg.payloadlen = strlen(pubmsg.payload);
    pubmsg.qos = 0;
    pubmsg.retained = 0;
    pubmsg.dup = 0;

    rc = MQTTPublish(&c, "/lanxiang/meirong/lili", &pubmsg);
    printf("Published %d\n", rc);

    MQTTDisconnect(&c);
    NetworkDisconnect(&n);
    return 0;
}

订阅方的示例代码为:

#include <stdio.h>
#include <memory.h>
#include "MQTTClient.h"

#include <signal.h>

//通过信号退出程序
volatile int toStop = 0;
void cfinish(int sig)
{
    signal(SIGINT, NULL);
    toStop = 1;
}

//新消息到达的回调函数
void messageArrived(MessageData* md)
{
    MQTTMessage* message = md->message;

    printf("%.*s\t", md->topicName->lenstring.len, md->topicName->lenstring.data);
    printf("%.*s\n", (int)message->payloadlen, (char*)message->payload);
}

int main(int argc, char** argv)
{
    int rc = 0;
    unsigned char buf[100];
    unsigned char readbuf[100];

    Network n;
    MQTTClient c;

    signal(SIGINT, cfinish);
    signal(SIGTERM, cfinish);

    NetworkInit(&n);
    NetworkConnect(&n, "test.mosquitto.org", 1883);
    MQTTClientInit(&c, &n, 1000, buf, 100, readbuf, 100);

    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;       
    data.willFlag = 0;
    data.MQTTVersion = 3;
    data.clientID.cstring = "lili";
    data.keepAliveInterval = 10;
    data.cleansession = 1;

    // 连接mqtt服务器
    rc = MQTTConnect(&c, &data);
    printf("Connected %d\n", rc);

    // 订阅mqtt消息
    rc = MQTTSubscribe(&c, "/lanxiang/meirong/lili", 0, messageArrived);
    printf("Subscribed %d\n", rc);

    while (!toStop)
    {
        MQTTYield(&c, 1000);
    }

    printf("Stopping\n");

    MQTTDisconnect(&c);
    NetworkDisconnect(&n);

    return 0;
}

JavaScript语言mqtt客户端示例

使用npm命令安装JavaScript的mqtt客户端库。

npm install mqtt

发布方的示例代码为:

var mqtt = require('mqtt')
var client = mqtt.connect('mqtt://test.mosquitto.org')

client.on('connect', function () {
  client.publish('/lanxiang/meirong/lili', '是丽丽吗')
  client.end()
})

订阅方的示例代码为:

var mqtt = require('mqtt')
var client = mqtt.connect('mqtt://test.mosquitto.org')

client.on('connect', function () {
  client.subscribe('/lanxiang/meirong/lili', function (err) {
    if (err) {
        console.log(err);
    }
    else{
        console.log("subscribe succeed!");
    }
  })
})

client.on('message', function (topic, message) {
  console.log(message.toString())
  client.publish('/lanxiang/wajueji/xiaoming', '准备睡了,有空再聊')
  client.end()
})

云厂商mqtt接入说明

AWS,阿里云等云厂商,都提供了物联网设备接入的云平台,虽然它们使用的也是mqtt,但是使用上述标准的mqtt客户端库是无法接入这些物联网云平台的,必须使用云厂商自己的mqtt SDK才能接入,这是因为此类物联网云平台添加了特有的功能(而标准的mqtt客户端库并没有这些特有的功能),主要包括

  • 特有的安全认证,mqtt默认只有用户名和密码的认证,而云厂商提供了自己特有的认证方式,其安全性会更好
  • 特有的业务逻辑,云厂商一般需要先通过Web控制台创建设备信息(包括设备所属产品,设备ID,设备密钥等),再把设备信息烧写到设备固件中,然后才可以连接到云平台

云厂商一般都会提供详细的设备接入文档和接入SDK,可以去阿里云mqtt SDK自行围观阿里的mqtt客户端库。

什么是OPC UA

OPC UA是一套通信协议标准,完成设备与设备,设备与应用之间的数据交互。源码先生的物联网IoT协议之mqtt快速入门教程中的mqtt也是一套数据交互的协议标准,两者虽然协议内容不同,但最终目的一致,都是为了实现不同系统的数据交互。

OPC UA前身是OPC,第一个OPC规范在1996年发布,包括一整套接口、属性和方法的标准集;OPC基于Windows操作系统的COM技术,所以只能运行在Windows上。

OPC UA是OPC的重大升级,在平台独立性、安全性,可靠性等方面做出了升级,更能适应现代工业通信的需求,虽然升级内容很多,但OPC UA 对比OPC并无革命性的变化。

OPC UA用在什么场景

OPC主要用在自动化控制系统、仪器仪表及过程控制系统,具有很明显的工业基因,而且OPC发展这么多年,也很少扩展到非工业领域。

随着近年物联网、工业4.0、工业互联网、IT和OT(Operational Technology)融合等需求的出现,人们希望把工业设备融入到物联网中,深耕工业领域的OPC UA,自然成为大家关注的重点对象!

通过对比mqtt入门OPC UA

mqtt和OPC UA都是为了实现不同系统的数据交互,mqtt相对比较简单,mqtt通过发布订阅实现数据交互,而OPC UA要复杂不少,通过对比两者的差异,对入门OPC UA很有帮助。

拓扑结构的对比

在mqtt中,设备以及应用程序都作为客户端连接到mqtt服务器(Broker),形成以mqtt服务器为中心的拓扑结构。

在OPC UA中,设备不是作为客户端,而是作为OPC UA Server提供各种服务,应用程序作为客户端连接到设备,调用OPC UA Server提供的各种服务。

OPC UA中,设备除了作为OPC UA Server,也可以同时作为客户端连接到其他设备,形成非中心化的拓扑结构。

业务模型对比

mqtt标准中没有定义业务模型,mqtt服务器只是个中转站,用来透传转发多个客户端的消息。应用程序需要在应用层自定义业务模型,主流物联网云平台都使用类似json的格式描述业务模型,阿里云的物模型如下图

OPC UA中,使用面向对象的方式定义业务模型。面向对象中通过类(包括类成员变量,类成员函数,类实例),以及类之间的继承关系实现对业务的建模,而OPC UA的通过节点,以及节点之间的引用关系实现对业务的建模。

OPC UA的节点(Node)

节点是OPC UA数据交互的基本单元,客户端和服务器之间的交互通信,都是基于节点进行的。OPC UA中预定义了8种节点:

  • ObjectNode
  • ObjectTypeNode
  • VariableNode
  • VariableTypeNode
  • MethodNode
  • ReferenceTypeNode
  • DataTypeNode
  • ViewNode

节点的属性用来描述节点,下面是所有节点共有的通用属性。

OPC UA的引用(Reference)

引用描述了两个节点之间的关系,用来把多个节点关联起来,OPC UA预定义了多种引用,下面重点介绍几种常用的引用。

hasTypeDefinition

hasTypeDefinition用来描述面向对象中类、类实例之间的关系

ObjectNode的hasTypeDefinition引用,指向了一个ObjectTypeNode,表示该ObjectNode的类型;
VariableNode的hasTypeDefinition引用,指向一个VariableTypeNode,表示该 VariableNode的类型。

hasSubType

hasSubType用来描述面向对象中的继承关系。当子类从父类继承后,子类拥有一个hasSubType引用指向父类。

hasComponents

hasComponents类似设计模式中的组合模式。

  • ObjectNode一般都由多个VariableNode组成,ObjectNode包含某个VariableNode时,ObjectNode拥有一个hasComponents引用,指向该VariableNode;
  • VariableNode也可以包含子VariableNode,此时也用hasComponents描述它们的关系。

Organizes

Organizes用来指明两个节点的层次结构,可以类比为文件夹和文件的关系,通过Organizes,可以把多个文件(节点)组织到同一个文件夹(父节点)下面。

完整的引用类图如下。

OPC UA中的服务(Service)

服务可以看做是OPC UA Server提供的API集合,也可以看做是RPC(Remote Procedure Call)接口集合,服务以方法的方式提供出来,服务使用了类似Web的请求-应答机制,当客户端调用一个服务时,客户端发送一个请求给服务器,服务器处理完成请求后,返回响应消息给客户端。

客户端访问服务器提供的所有功能,都是通过调用服务完成。

OPC UA预定义了37个标准服务,按功能分类如下图

其中常用的服务有:

  • 通过读写服务,可以获取服务器上指定节点指定属性的值;
  • 调用服务,可以执行服务器上执行节点的方法;
  • 订阅数据变化和时间,可以监控服务器数据的变化。

语义化对比

mqtt标准中没有定义语义化的内容,应用程序要想知道设备提供了哪些功能/服务,只能靠应用程序和设备双方提前约定,或者通过阅读设备提供的说明文档。

OPC UA Server中节点的通用属性BrowseName、DisplayName、Description等描述了节点的属性和功能,应用程序连接到OPC UA Server后,通过浏览这些属性就可以了解设备提供的功能和服务。

发布订阅对比

mqtt和OPC UA都提供了发布订阅的功能,OPC UA的发布订阅功能用来实现设备数据的监控,但设备数据有变化时,订阅者会实时收到通知。

OPC UA之Hello World

上面的概念很抽象,要先对OPC UA有初步的认识,还是来个Hello World比较靠谱。

选择OPC UA Client

免费且好用的OPC UA客户端,源码先生推荐Unified Automation公司的UAExpert,在其官网https://www.unified-automation.com/ 上注册后可以免费下载,也点击这里下载【Linux平台】【win32平台】

选择”在线OPC UA Server”

相比mqtt官方提供了一大票公开的mqtt测试服务器地址,公开的在线OPC UA Server少的可怜,源码先生在互联网上认真了搜了一番,只能找到唯一的一个,即opc.tcp://opcua.rocks:4840/ 。

UAExpert连接”在线OPC UA Server”

启动UAExpert,依次选择[Server]–[Add]–[Advanced],按下图输入信息。

通过右键菜单连接服务器。

第一次连接时,会提示服务器证书的警告,此时需要选择信任(Trust)服务器的证书。

连接成功后,会在地址空间中显示出服务器的全部节点。

展开节点后,会发现opc.tcp://opcua.rocks:4840/提供了一个Hello World的方法,可通过右键菜单调用该方法。

Hello World方法需要输入参数,这里填入测试字符串“www.debugself.com” ,并点击Call按钮。

服务器执行Hello World方法,返回执行结果。通过输出参数可以看出,Hello World方法,简单的把输入参数前面添加了Hello后,然后返回给客户端的。

部署本地OPC UA Server

上面的“在线OPC UA Server”网速很慢,测试时可能连接失败,这是也可以自己部署本地OPC UA Server。https://github.com/Pro/opcua-animal-server 是一个使用open62541构建OPC UA Server的示例,为了方便部署,我把opcua-animal-server构建成docker镜像(构建过程请参考 https://github.com/gdbself/opcua-animal-server/ ),方便一键本地部署。

以Ubuntu系统为例,首先要安装docker(docker已经是云端开发的基础设施,不了解docker的话,有必要借此学习下docker的用法)。

apt-get install docker

运行下面的docker命令部署本地OPC UA Server(真的一键部署,很方便,有木有?)。

docker run -d -p 4840:4840 debugself/opcua-animal-server:20191125

UAExpert连接“本地OPC UA Server”

启动UAExpert,依次选择[Server]–[Add]–[Advanced],按下图输入信息。

注意,请把图中的192.168.170.128替换为自己Ubuntu电脑的IP地址。

连接OPC UA Server成功后,可以看到服务器地址空间中显示了所有节点。选中Cat的Name节点,在右侧的属性框中可以看到这只猫的Value属性值为Cattie,意为这是猫的名称为Cattie。

OPC UA的学习资料

学习OPC UA的细节,源码先生推进阅读 https://open62541.org/doc/current/index.html ,比官方的文档简单明了;
C语言实现的开源OPC UA:https://github.com/open62541;
官方OPC UA标准文档:https://reference.opcfoundation.org/v104;
官方提供的OPC UA实现:https://github.com/OPCFoundation ,包括C、C++、C#、Java语言实现的OPC UA Server和Client。
OPC UA中的概念很多,初学者会感觉OPC UA很复杂,这里再强调一次,OPC UA本质是按照面向对象的方式对业务建模,搞不懂OPC UA时,按照面向对象的思路,基本可以做到拨云见日。

本文引自:

https://www.debugself.com/2020/03/23/Protocol_guide/

作者:李拜天  创建时间:2022-05-24 08:17
最后编辑:李拜天  更新时间:2023-01-17 14:40