今天继续聊SOA的话题,前面聊过了 SOME/IP DDS ,很多文章提到SOA协议,还会把HTTP和MQTT也放进来讨论。但个人认为,目前只有SOME/IP和DDS适合作为车载SOA的中间件方案,而HTTP和MQTT则更适合应用于车联网云端交互的场景。

MQTT是一个客户端服务端架构的发布/订阅模式的消息传输协议。它的设计思想是轻巧、开放、简单、规范,因此易于实现。这些特点使得它对很多场景来说都是很好的选择,包括受限的环境如机器与机器的通信(M2M)以及物联网环境(IoT),这些场景要求很小的代码封装或者网络带宽非常昂贵。

MQTT运行在TCP/IP之上,它有以下特点:

  • 使用发布/订阅消息模式,提供了一对多的消息分发和应用之间的解耦。

  • ​消息传输不需要知道负载内容。

  • 提供三种等级的服务质量:“最多一次”,尽操作环境所能提供的最大努力分发消息。消息可能会丢失。例如,这个等级可用于环境传感器数据,单次的数据丢失没关系,因为不久之后会再次发送;“至少一次”,保证消息可以到达,但是可能会重复;“仅一次”,保证消息只到达一次。

  • 很小的传输消耗和协议数据交换,最大限度减少网络流量。

  • 连接异常断开时,能通知到相关各方。

如图,不管对于CP还是AP Autosar,都没有提供MQTT的支持。因此,对于跑Autosar的ECU来说,很难实施MQTT Client,更不要说Broker了。对于非Autosar的ECU来说,MQTT Client的实施是容易的,但是能不能作为Broker就得打个问号了。前面讨论过几种通信模型,MQTT是典型的Broker模型:

互联网通常具备性能强大的后端服务器,完全有能力部署Broker,承受百万级别的连接,还可以支持身份认证、动态主题、主题过滤、集群等,尤其是主题的管理,我认为是不可或缺的功能点,ECU可以实现吗?即使可以,我想对性能的挑战也会不小。因此,对于非Autosar的ECU来说,MQTT更多的应用场景是实现MQTT的客户端,与云端进行通信,可能还需要进行云端消息与车载SOA消息间的转化,从而实现远程控制、远程升级、大数据采集等常见功能。

下面我以初步体验一下MQTT作为小目标,快速搭建了一个Paho MQTT Client + Mosquitto MQTT Broker的试验环境,先简单介绍一下它俩:

Eclipse Mosquito 是一个开源(EPL/EDL许可)消息代理,它实现了MQTT协议版本5.0、3.1.1和3.1。Mosquito是轻量级的,适用于从低功耗单板机到全服务器的所有设备。

Eclipse Paho 以各种编程语言提供了MQTT客户端的开源(EPL/EDL许可)实现:

以前觉得Eclipse是做IDE的,还不咋好用,又肤浅了。

下面以Paho C 同步接口为例,实现两个客户端,一个订阅主题,一个发布主题消息,通过Broker进行通信,关于下载和安装,依然写在README中,关注公众号回复“演示代码”就可以看到完整Demo代码的Github链接。运行结果如下:

从这个示例,可以看出,两个客户端之间彼此独立,它们只分别与Broker进行通信,代码比较简单,按照官方示例的调用顺序,配置通信参数就可以了,用Wireshark抓取数据包(3.4.2版本完美支持MQTT协议):

现在问题来了,在互联网环境中,这样的通信是非常不安全的,所有消息几乎都在裸奔,并且只要连接建立起来,任何应用都可以订阅/发布任何主题的任何消息,显然,这是不能接受的。那么,如何实现常用的双向认证呢?首先,在编译Paho C++ Client库时需要打开PAHO_WITH_SSL开关,接下来用脚本(在生产环境中,可以定制生成证书的脚本)简单制作测试用的CA:

mkdir myCA
wget https://github.com/owntracks/tools/raw/master/TLS/generate-CA.sh
chmod +x generate-CA.sh
# 生成服务端证书
./generate-CA.sh server
# 用生成的CA,生成客户端证书
openssl genrsa -out client.key 2048
openssl req -new -out client.csr -key client.key -subj "/CN=client/O=example.com"
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAserial ./ca.srl -out client.crt -days 3650 -addtrust clientAuth

简单测试一下,CA是否可用:

openssl verify -CAfile ca.crt server.crt
openssl verify -CAfile ca.crt client.crt

创建配置文件ca_test.conf:

listener 8883
cafile /home/lxl/Develop/myCA/ca.crt
certfile /home/lxl/Develop/myCA/server.crt
keyfile /home/lxl/Develop/myCA/server.key
require_certificate true
use_identity_as_username true

用这个配置文件启动mosquitto:

mosquitto -c ./ca_test.conf

用mosquitto提供的测试程序,验证SSL连接是否成功:

mosquitto_sub -h 127.0.0.1 -p 8883 -t "TestTopic" --cafile /home/lxl/Develop/myCA/ca.crt --cert /home/lxl/Develop/myCA/client.crt --key /home/lxl/Develop/myCA/client.key
mosquitto_pub -h 127.0.0.1 -p 8883 -t "TestTopic" -m "this is SSL" --cafile /home/lxl/Develop/myCA/ca.crt --cert /home/lxl/Develop/myCA/client.crt --key /home/lxl/Develop/myCA/client.key

验证OK后,可以着手改代码了,主要是在建立连接前配置SSL选项的参数(具体可以查看完整代码):

MQTTClient_SSLOptions ssl_opts = MQTTClient_SSLOptions_initializer;
conn_opts.ssl = &ssl_opts;
conn_opts.ssl->trustStore = "/home/lxl/Develop/myCA/ca.crt";
conn_opts.ssl->keyStore = "/home/lxl/Develop/myCA/client.crt";
conn_opts.ssl->privateKey = "/home/lxl/Develop/myCA/client.key";
conn_opts.ssl->enableServerCertAuth = true;

运行效果和前面基本一致,再用Wireshark捕获一下数据包看看:

Nice,终于不再裸奔啦~

双向认证只是安全措施的一种,还可以加持其他措施,如身份认证、针对主题的权限管理等,以增强安全性。

最后,和HTTP相比,MQTT是为物联网而生的协议,主要体现在:它比HTTP更加轻量,协议更精简,消息头更短,这些都提高了它的响应时间和吞吐量,并降低了开销和功耗。MQTT也有不适用的场景,比如大文件、音视频等,就要考虑其他传输方案了。

是 Eclipse 实现的基于 MQTT 协议的客户端,本软件包是在 Eclipse 源码包的基础上设计的一套 MQTT 客户端程序。 paho - mqtt 软件包功能特点以及 MQTT 协议介绍请参考 。 1.1 目录结构 paho - mqtt 软件包目录结构如下所示: paho mqtt ├───docs │ └───figures // 文档使用图片 │ │ api.md // API 使用说明 │ │ introduction.md // 介绍文档 │ │ principle.md // 实现原理 │ │ README.md // 文档结构说明 项目运行时报如下异常: Mqtt Exception (0) - javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names matching IP address x.x.x.x found at org.eclipse. paho .client. mqtt v3.internal.ExceptionHelper.create Mqtt Exception(Exc openssl 交叉编译 ./config no-asm shared linux-armv4 no-async – prefix=/home/openssl-master/nuc980 // linux-armv4 =>>target // no-async>undefined reference ***context paho mqtt -c 交叉编译 cmake … -D PAHO _BUILD_STATIC=TRUE -D PAHO _WITH_SSL=TRUE - DCMKAE 1.通过 http / http s 连接 mosquitto mosquitto 作为一个消息代理, 客户端与 mosquitto 服务端的通信时基于 MQTT 协议的, 而现在的主流 web 应用时呈现在浏览器中, 这意味着用户与服务端只能通过 HTTP 或者 HTTP S 这类浏览器能理解的协议传输, 所以后端还要建立一个代理层, 将 HTTP 协议传输的内容解析一下以 MQTT 协议发送到 mosqu... 目录 Mosquitto 与 Eclipse Paho MQTT TLS使能备忘为什么使用 MQTT 原型系统构成服务端软件环境客户端软件环境使用OpenSSL构建TLS Mosquitto 与 Eclipse Paho MQTT TLS使能备忘 最近使用 Mqtt 协议为公司的分布式系统 搭建 了一个“简陋”的原型通信框架,实际使用下来效果还不错,因此打算对通信进行TLS加密,使其能够真正用于生产中。本文主要记录使用 Mosquitto 作为服务端及测试客户端, Paho MQTT (Python)作为客户端的使用配置下,用o const name = new Date().getTime() + 'client' const client = new Paho MQTT .Client('www.100link.net', Number(61615), nam... 找到如下 MQTT 文件(下图),加入到工程中。 2.打开 MQTT Client.h 头文件,在其中定义如下程序(下图),定时器接口,网络接口,定时器的5个函数,如果已有,屏蔽已有的。 #define int_ValMax 0xffffffff//int stm32 32位 typedef struct Timer Timer;//定时器接口 对外 struct Timer {   在文章 Paho - MQTT C Cient的实现中,我介绍了如何使用 Paho 开源项目创建 MQTT Client_pulish客户端。但只是简单的介绍了使用方法,而且客户端的结果与之前介绍的并不吻合,今天我就结合新的例子,给大家讲解一下 Paho 使用 MQTT 客户端的主要过程。   如同前面介绍的, MQTT 客户端分为同步客户端和异步客户端。今天主要讲解的是同步客户端,结构还是如同步客户端中 paho mqtt 遇到诸如“此应用程序只需要向另一个服务器发送值”之类的问题时,总会有一种诱惑,将其简化为打开套接字并发送值之类的事情。 但是,这个简单的主张很快就在生产中瓦解了。 除了必须编写系统的服务器端之外,开发人员还必须应对以下事实:网络不是100%可靠的,而围绕我们的无线和移动网络在设计上并不可靠,因此很可能需要访问控制和加密。 编写代码来解决这个问题,最终会遇到更加复杂,难以测... 1.客户端支持gmssl 客户端首先编译gmssl ./Configure no-asm no-async shared --cross-compile-prefix=mips-openwrt-linux- --prefix=$STAGING_DIR/usr --openssldir=/usr/ssl linux-mips32 –openssldir参数表示实际使用的时候,链接的配置路径 no-async表示关闭异步,但是实际编译会有问题,注意由于这个导致的问题,基本都可以通过 mosquitto .conf 配置 mosquitto .conf man page http s:// mosquitto .org/man/ mosquitto -conf-5.html 配置TLS单向 认证 修改 mosquitto .conf文件,可直接在文件末尾追加 listener 8883 protocol mqtt cafile C:\ mosquitto \ca\ca.crt certfile C:\ mosquitto \ca\ser