物联网IoT应用层协议对比

随笔2个月前发布 陈小六
4 0 0

物联网IoT应用层协议浅谈及对比

在开发物联网iot的项目中,我们采用的协议一般要有以下的特点:

全双工长连接:双向数据流,可实现硬件设备的控制和事件上报业务。
可靠的连接:物联网设备通常用于监测、数据同步、远程控制等场景,一个可靠的连接才能避免重要数据的丢失。
支持窄带宽开销小:物联网嵌入式设备一般只有几K的内存,窄带宽意味着比较小的内存开销。
低延时:低延时对于设备的及时控制和响应有很大的帮助
安全性高:物联网设备更注重的是安全,不管是泛家庭物联网还是工控物联网,安全必不可少。

根据以上特点,目前主流的物联网IoT平台开发的应用层协议有:

MQTT:基于TCP的全双工订阅发布模型的二进制协议
WebSocket:基于TCP的全双工隧道通信的二进制协议
CoAP:基于UDP的低功耗窄带宽不可靠传输的二进制协议
由于http协议请求-响应式的逻辑,无法做到全双工通信,所以在物联通IoT的建设中一般不会采用http作为主要通信方式,而在一些及时的无上下文关联的事件上报业务中,也可以采用http方式进行通信。

一、MQTT协议

MQTT是用于物联网(IoT)的OASIS标准消息传递协议。它被设计为一种非常轻量级的发布/订阅消息传输,非常适合使用较少的代码占用和最小的网络带宽连接远程设备。

MQTT是基于TCP/IP协议栈的,基于客户端-服务端的发布/订阅消息模式,支持一对多的消息发布。

重要的名词

发布者:客户端的一种模式,发布者Publish是发出消息的一方
订阅者:客户端的一种模式,订阅者Subscribe是接收消息的一方
Topic:发布订阅消息传递基于的一种过滤器,可以简单理解为发布订阅者根据不同的topic发送和接收不同的消息
Broker:服务端,用于接收客户单消息并过滤和中转,推送给对应客户端
QoS:全称:Quality of Service levels,属于mqtt协议的一种规范,用于定义消息的质量等级

0:发送后不关心是否被接收,不保证消息的丢失和重复
1:承诺消息至少传送一次,存在ACK机制和重发机制,但无法保证消息重复。
2:有严格的ACK和重发机制且含有唯一的ID,保证消息成功且传送一次,开销较大。

二、Websocket协议

Websocket的出现是为了解决web开发中标准的http协议无法支持全双工通信,浏览器和服务器之间无法双向通信,websocket是直接基于TCP通信的基础上复用HTTP的握手通道,并建立websocket通信隧道,属于应用层协议。
Websocket也是一种轻量级的二进制通信协议,拥有较小的网络开销,所以在嵌入式开发中,也可以直接通过c来实现。

Websocket是基于客户端-服务器模式的,由于支持全双工,所以实时性通信更好。

复用HTTP握手通道:
为了向前兼容, WebSocket 协议使用 HTTP握手协议,通过在头域中的 Upgrade 协议升级机制来进行 WebSocket 握手, 当握手完成之后, 客户端和服务端就可以依据WebSocket 协议的规范格式进行数据传输。
第一步,由客户端通过HTTP请求与WebSocket服务端协商升级协议。
第二步,协议升级完成后,后续的数据交换则遵照WebSocket的协议。

2.1、客户端发起协议升级的请求

基于标准的HTTP协议格式进行请求,Host、Origin、Cookie等请求首部会照常发送。在握手阶段,可以通过相关请求首部进行 安全限制、权限校验等。

GET / HTTP/1.1
Host: 10.10.0.35:80
Origin: http:// 10.10.0.35:80
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Version: 13
Sec-WebSocket-Protocol: ws
Sec-WebSocket-Key: w4v7O6xFTi36lq3RNcgctw==

Connection: Upgrade,表示要升级协议。
Upgrade: websocket,表示要升级到websocket协议。
Sec-WebSocket-Version: 13,表示websocket的版本。如果服务端不支持该版本,需要返回一个Sec-WebSocket-Version 的header,里面包含服务端支持的版本号。
Sec-WebSocket-Protocol:指出当前协议的格式,ws则为不加密,wss则为加密。
Sec-WebSocket-Key:与后面服务端响应首部的Sec-WebSocket-Accept是配套的,提供基本的防护。

2.2、服务器响应协议升级

HTTP/1.1 101 Switching Protocols
Connection:Upgrade Upgrade: websocket
Sec-WebSocket-Accept: Oy4NRAQ13jhfONC7bP8dTKb4PTU=

状态代码101表示协议切换。到此完成协议升级,后续的数据交互都按照新的协议来

Sec-WebSocket-Accept根据客户端请求首部的Sec-WebSocket-Key计算出来。
计算公式为:

将Sec-WebSocket-Key跟25SMXIDA-E914-4CCA-9VCA-C5AS123F85B11拼接。
通过SHA1计算出摘要,并转成base64字符串。

伪代码如下:

toBase64(sha1(Sec-WebSocket-Key + 25SMXIDA-E914-4CCA-9VCA-C5AS123F85B11))

三、CoAP协议

CoAP 是一种基于UDP不可靠连接的,具有低开销的简单二进制协议,专为受限设备(如微控制器)和受限网络而设计。
CoAP分为:消息层和请求/响应层,以此来尽可能避免UDP传输的不可靠性,每个 CoAP 消息都有一个唯一的 ID;这对于检测消息重复非常有用。

协议术语

Endpoint: 参与 CoAP 协议的实体。通常,终结点与主机一起标识
Sender: 发送消息的实体
Recipient: 发送消息的目标
Client: 发送请求的实体和响应的目标
Server: 从客户端接收请求并向客户端发送响应的实体

四、三者对比

协议类型
优点

缺点
主要使用场景
MQTT 1、轻量级的二进制协议
2、可靠连接(ACK机制可选),QoS等级可选
3、生态完善(很多的客户端和服务器开源库)
4、发布订阅模式解耦业务,支持一对多
5、支持心跳保活和离线消息遗言等
6、支持SSl加密传输
1、开发复杂度高
2、协议较复杂学习成本高
全双工通信场景均可以使用,特别用于物联网IoT平台建设,嵌入式设备通信
Websocket 1、轻量级的二进制协议
2、基于TCP的可靠长连接,支持心跳机制
3、协议简单,学习成本低(客户端和服务器都有开源库)
4、天生用于web开发且基于HTTP握手机制更加便捷
5、支持SSl加密传输
1、服务器和客户端必须在线并建立连接,不支持离线消息
2、不支持一对多通信
全双工通信场景,特别是web服务器与客户端的通信、推送业务、也可以用于物联网IoT平台与嵌入式设备通信
CoAP 1、轻量级的二进制协议
2、帧头仅4字节,适合在低功耗受限设备使用
3、资源发现类似URI
1、基于UDP连接可靠性和安全性较低
2、扩展性差
适合在弱网环境和受限设备使用

五、开发开源库选择

5.1 MQTT开源选择

MQTT-Broker推荐

Mosquitto:Eclipse Mosquitto使用 C 语言实现的 MQTT 服务器,轻量级。
github:https://github.com/eclipse/mosquitto
Mosquitto 提供了基本的日志和调试功能,用于监控代理状态和故障排除。然而,它缺乏先进的管理和监控功能,使用户难以从其运行状态获得更多洞察进行性能优化。

EMQX:Erlang实现的分布式Broker端,内置强大的规则引擎,同时支持其他 IoT 协议。
github:https://github.com/emqx/emqx
EMQX 通过 HTTP API 和 Dashboard 提供丰富和可视化的监控功能,使其更容易监控和管理。

MQTT-客户端推荐

paho_mqtt:Eclipse基金会开发的开源mqtt客户端,支持多种语言,强烈推荐。

Java:- Eclipse Paho Java
C:支持嵌入式使用

Eclipse Paho C
Eclipse Paho Embedded C :嵌入式C使用

C++:

Eclipse Paho C++、Eclipse Paho Embedded C++
libmosquittopp

Python:Eclipse Paho Python – 是Mosquitto 客户端发展而来

ActiveMQ Client:ActiveMQ支持Mqtt,在Java工程中用的比较广泛

5.2 Websocket开源选择

5.2.1 基于C库的libwebsockets

Libwebsockets (LWS)是一个灵活的、轻量级的纯C库,用于使用非阻塞事件循环,以很小的占用空间轻松实现现代网络协议。
常用于:C++的websocket服务器开发,C/C++的嵌入式的客户端开发使用。
官网地址:https://libwebsockets.org/

5.2.2 JAVA生态中的websocket

由于websocket诞生之处就是为了解决web的长连接全双工问题的,所以java生态中可以选择的websocket插件非常之多,以下两个为例。

java-websocket.jar : java的原生jar包https://github.com/TooTallNate/Java-WebSocket

<dependency>
	<groupId>org.java-websocket</groupId>
	<artifactId>Java-WebSocket</artifactId>
	<version>1.5.3</version>
</dependency>

spring-boot-starter-websocket:spring boot框架中的依赖。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.7</version>
    <relativePath/> 
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>
</dependencies>

5.2.3 Python生态中的websocket

Python生态中的websocket模块也非常之丰富,对于一个不使用框架的python开发者来说,一般可以选择的websocket第三方库有:

Tornado:pip install tornado,常用的websocket服务模块,可用于生产环境。
websockets:pip install websockets,支持异步asynio,可搭建服务,开用于生产环境。
aiowebsocket:pip install aiowebsocket,异步客户端。

在常用的Python Djangoweb框架中也集成了支持websocket的第三方库:Channels
安装方式:

pip install channels
pip install chnanels_redis
© 版权声明

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...