27、IoT边缘到云的协议解析

IoT边缘到云的协议解析

1. MQTT - SN 协议

1.1 代理与拓扑结构

在 MQTT - SN 拓扑中,代理的行为与 MQTT 类似。无线传感器可以与 MQTT - SN 网关通信,这些网关将 MQTT - SN 转换为 MQTT 或其他协议形式;也可以与转发器通信,转发器只是将接收到的 MQTT - SN 帧封装成 MQTT - SN 消息转发给网关。

1.2 网关类型

MQTT - SN 中的网关有两种不同的角色:
- 透明网关 :管理来自传感器设备的多个独立 MQTT - SN 流,并将每个流转换为 MQTT 消息。它与 MQTT - SN 连接和到代理的 MQTT 连接具有一对一的关系。
- 聚合网关 :将多个 MQTT - SN 流合并为较少数量的 MQTT 流发送到云 MQTT 代理。虽然设计更复杂,但可以减少通信开销和服务器上同时打开的连接数量。要使聚合网关拓扑正常工作,客户端需要发布或订阅相同的主题。

1.3 网关广告和发现

由于 MQTT - SN 的拓扑比 MQTT 稍微复杂,因此使用发现过程来通过多个网关和转发器节点建立路由。加入 MQTT - SN 拓扑的网关首先绑定到 MQTT 代理,然后可能会向连接的客户端或其他网关发送 ADVERTISE 数据包。网络中可以存在多个网关,但客户端只能连接到单个网关。客户端负责存储活动网关及其网络地址的列表,该列表由各种 ADVERTISEMENT 和 GWINFO 消息广播构建而成。

为了辅助发现和广告,MQTT - SN 中有几种新消息:
- ADVERTISE :由网关定期广播以宣传其存在。
- SEARCHGW :客户端在搜索特定网关时广播。消息的一部分是半径参数,用于指定 SEARCHGW 消息在网络拓扑中应遵循的跳数。
- GWINFO :网关在收到 SEARCHGW 消息时的响应,包含网关 ID 和网关地址,仅在客户端发送 SEARCHGW 时广播。

1.4 MQTT 与 MQTT - SN 的区别

区别点 MQTT MQTT - SN
CONNECT 消息数量 1 个 3 个,额外两个用于显式传输 Will 主题和 Will 消息
运行介质 - 可在简化介质和 UDP 上运行
主题表示 主题名称 短的两字节主题 ID 消息,以适应无线网络的带宽限制
主题使用 - 预定义主题 ID 和短主题名称无需注册即可使用
发现机制 引入发现过程,帮助客户端找到服务器和网关的网络地址
cleanSession 特性 - 扩展到 Will 功能,客户端订阅和 Will 数据都可保留
keepAlive 过程 - 修订后的 keepAlive 过程,支持睡眠客户端

2. 受限应用协议(CoAP)

2.1 CoAP 概述

CoAP 是 IETF(RFC7228)的产物,IETF 受限 RESTful 环境(CoRE)工作组于 2014 年 6 月创建了该协议的第一稿。它专门为受限设备设计,核心协议基于 RFC7252。CoAP 专为边缘节点之间的机器对机器(M2M)通信而定制,还支持通过代理映射到 HTTP,以实现数据跨互联网传输。

与标准 HTTP 相比,CoAP 在提供类似资源寻址结构的同时,具有更低的资源和带宽需求。一些 CoAP 实现的性能比类似硬件上的 HTTP 等效实现高 64 倍。以下是 CoAP 和 HTTP 在字节/事务、功率和电池寿命方面的对比:
|协议|字节/事务|功率|电池寿命|
| ---- | ---- | ---- | ---- |
|CoAP|154|0.744 mW|151 天|
|HTTP|1451|1.333 mW|84 天|

2.2 CoAP 架构细节

CoAP 基于用轻量级功能替代 HTTP 繁重功能的概念,用于物联网。它不是 HTTP 的替代品,因为它缺少一些功能,HTTP 需要更强大和面向服务的系统。CoAP 的特点总结如下:
- 类似 HTTP
- 无连接协议
- 通过 DTLS 实现安全,而不是 HTTP 传输中的 TLS
- 异步消息交换
- 轻量级设计,资源需求低,头部开销小
- 支持 URI 和内容类型
- 基于 UDP,而普通 HTTP 会话使用 TCP/UDP
- 无状态 HTTP 映射,允许代理桥接到 HTTP 会话

CoAP 有两个基本层:
- 请求/响应层 :负责发送和接收基于 RESTful 的查询。REST 查询搭载在 CON 或 NON 消息上,REST 响应搭载在相应的 ACK 消息上。
- 事务层 :使用四种基本消息类型处理端点之间的单消息交换,还支持多播和拥塞控制。

2.3 CoAP 与 HTTP 对比

CoAP 在上下文、语法和使用上与 HTTP 相似,寻址方式也类似。在最高级别,CoAP 使用与 HTTP 相同的请求,如 GET、PUT、POST 和 DELETE,响应代码也类似,例如:
- 2.01:创建
- 2.02:删除
- 2.04:更改
- 2.05:内容
- 4.04:未找到(资源)
- 4.05:方法不允许

典型的 CoAP URI 形式为:coap://host[:port]/[path][?query]

2.4 CoAP 系统的主要参与者

  • 端点 :CoAP 消息的源和目的地,具体定义取决于所使用的传输方式。
  • 代理 :由 CoAP 客户端委托执行请求的 CoAP 端点。可以减少网络负载、访问睡眠节点并提供安全层。代理可以是客户端显式选择的(正向代理),也可以用作原位服务器(反向代理),还可以将一个 CoAP 请求映射到另一个 CoAP 请求或转换为不同的协议(交叉代理)。
  • 客户端 :请求的发起者,响应的目的地端点。
  • 服务器 :请求的目的地端点,响应的发起者。
  • 中间者 :对源服务器既充当服务器又充当客户端的客户端,代理就是一种中间者。
  • 源服务器 :给定资源所在的服务器。
  • 观察者 :观察者客户端可以使用修改后的 GET 消息进行注册。当所监视的资源状态发生变化时,服务器会向观察者发送通知。这类似于 MQTT 的订阅模型。

2.5 CoAP 消息格式

由于基于 UDP 传输,连接可能不可靠。为了补偿可靠性问题,CoAP 引入了两种消息类型,根据是否需要确认来区分,并且消息可以是异步的。CoAP 总共有四种消息:
- Confirmable(CON) :需要 ACK。如果发送 CON 消息,必须在 ACK_TIMEOUT 和(ACK_TIMEOUT * ACK_RANDOM_FACTOR)之间的随机时间间隔内收到 ACK。如果未收到 ACK,发送者会以指数级增加的间隔重复发送 CON 消息,直到收到 ACK 或 RST。这是 CoAP 的拥塞控制形式,有最大尝试次数限制。
- Non - confirmable(NON) :不需要 ACK,本质上是一种即发即弃的消息或广播。
- Acknowledgement(ACK) :确认 CON 消息,可以搭载其他数据。
- Reset(RST) :表示已收到 CON 消息,但上下文缺失,可以搭载其他数据。

2.6 CoAP 缓存和消息头

CoAP 允许消息在任何 CoAP 客户端(包括传感器和服务器)之间发送,并且包含简单的缓存模型。缓存通过消息头中的响应代码控制,Max_Age 选项用于控制缓存元素的生命周期,确保数据的新鲜度,默认值为 60 秒,最长可达 136.1 年。

CoAP 消息头设计独特,长度为 4 字节,典型请求消息的头仅为 10 到 20 字节,通常比 HTTP 头小 10 倍。其结构包括消息类型标识符(T)和唯一的消息 ID,代码字段用于跨通道信号错误或成功状态,头之后的所有其他字段都是可选的,包括可变长度的令牌、选项和有效负载。

2.7 CoAP 观察者和资源发现

CoAP 允许系统中存在观察者角色,客户端可以注册观察资源,当资源状态变化时,服务器会通知客户端。观察关系在发起客户端发送 RST 或另一个 GET 消息时结束。

CoAP 还提供资源发现机制,只需向 /.well - known/core 发送 GET 请求,就可以披露设备上已知资源的列表,还可以在请求中使用查询字符串应用特定过滤器。

2.8 CoAP 使用示例

以下是使用 Python 基于 aiocoap 库实现的 CoAP 客户端和服务器示例:

客户端实现
#!/usr/bin/env python3
import asyncio            #necessary for asynchronous processing in Python
from aiocoap import *     #using the aiocoap library

async def main():
    context = await Context.create_client_context()
    await asyncio.sleep(2)                         #wait 2 seconds after initialization
    payload = b"20.2 C"
    request = Message(code=PUT, payload=payload)
    request.opt.uri_host = '127.0.0.1'             #URI for localhost address
    request.opt.uri_path = ("temp", "celcius")     #URI for path to /temp/celcius
    response = await context.request(request).response
    print('Result: %s\n%r'%(response.code, response.payload))

if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
服务器实现
#!/usr/bin/env python3
import asyncio                         #necessary for asynchronous processing in Python
import aiocoap.resource as resource    #using aiocoap library
import aiocoap

class GetPutResource(resource.Resource):
    def __init__(self):
        super().__init__()
        self.set_content(b"Default Data (padded) ")

    def set_content(self, content):                #Apply padding
        self.content = content
        while len(self.content) <= 1024:
            self.content = self.content + b"0123456789\n"

    async def render_get(self, request):            #GET handler
        return aiocoap.Message(payload=self.content)

    async def render_put(self, request):            #PUT handler
        print('PUT payload: %s' % request.payload)
        self.set_content(request.payload)               #replaces set_content with received payload
        return aiocoap.Message(code=aiocoap.CHANGED, payload=self.content) #set response code to 2.04

def main():
    root = resource.Site()        #root element that contains all resources found on server
    root.add_resource(('.well-known', 'core'),              #this is the typical .well-known/core
                      resource.WKCResource(root.get_resources_as_linkheader)) #resource list for .well-known/core
    root.add_resource(('temp', 'celcius'), GetPutResource()) #adds the resource /tmp/celcius
    asyncio.Task(aiocoap.Context.create_server_context(root))
    asyncio.get_event_loop().run_forever()

if __name__ == "__main__":
    main()

3. 其他协议

除了 MQTT - SN 和 CoAP 之外,还有许多其他用于物联网(IoT)和机器对机器(M2M)部署的消息协议。下面将介绍两种较为常见的替代协议。

3.1 STOMP 协议

STOMP 即简单(或流式)文本消息导向中间件协议,是由 Codehaus 设计的基于文本的协议,用于与消息导向中间件进行交互。该协议的当前规范是 2012 年 10 月 22 日发布的 STOMP 1.2,并且可以免费使用。

3.1.1 协议特点
  • 语言兼容性 :用一种编程语言开发的代理可以接收用另一种编程语言编写的客户端发送的消息。
  • HTTP 语义 :使用类似 HTTP 的语义,如 SEND 命令,并带有目标字符串。但它不处理订阅主题或队列,需要代理解析消息并映射到客户端的主题或队列。
  • 多语言客户端 :有 Python(Stomp.py)、TCL(tStomp)和 Erlang(stomp.erl)等语言编写的客户端。
  • 服务器支持 :一些服务器具有原生 STOMP 支持,例如 RabbitMQ 可通过插件支持。此外,还有一些用特定语言(如 Ruby、Perl 或 OCaml)设计的服务器。

3.2 AMQP 协议

AMQP 即高级消息队列协议,是一种经过验证的消息导向中间件协议,被广泛应用于大规模数据处理场景,如摩根大通每天处理超过 10 亿条消息,海洋观测计划每天收集超过 8 TB 的海洋数据。

3.2.1 协议基础
  • 标准化 :由 ISO 和 IEM 标准化为 ISO/IEC 19464:2014,相关的正式工作组可在 www.amqp.org 找到。
  • 网络层次 :位于 TCP 栈之上,使用端口 5672 进行通信。数据在 AMQP 上进行序列化,消息以单位帧的形式广播。
  • 帧结构 :帧由头部、唯一的通道 ID、有效负载信息和尾部组成。每个通道只能与单个主机关联,消息被分配唯一的全局标识符。
3.2.2 协议特性
  • 流控制和消息导向 :是一种流控制、消息导向的通信系统,属于底层的有线协议,允许不同的消息服务(如 .NET(NMS)和 Java(JMS))相互通信。
  • 解耦发布者和订阅者 :尝试将发布者与订阅者解耦,与 MQTT 不同,它具有负载均衡和正式的排队机制。
  • 虚拟主机和交换器 :一个或多个具有自己命名空间、交换器和消息队列的虚拟主机可以驻留在中央服务器上。生产者和消费者订阅交换器服务,交换器接收发布者的消息并将数据路由到关联的队列。
3.2.3 交换器类型
  • 直接交换器 :将消息直接路由到一个队列。
  • 主题交换器 :使用模式对路由键进行通配符匹配,例如 *.temp.# 可以匹配 idaho.temp.celsius 和 wisconsin.temp.fahrenheit。
3.2.4 相关实现
  • RabbitMQ :是一个用 Erlang 编写的 AMQP 消息代理,被广泛使用。
  • 客户端 :有多种语言编写的 AMQP 客户端,如 Java、C#、Javascript 和 Erlang 编写的 RabbitMQ 客户端,以及 Python、C++、C#、Java 和 Ruby 编写的 Apache Qpid 客户端。

3.3 协议对比总结

协议 特点 适用场景
MQTT - SN 适用于无线网络,有网关发现机制,主题使用短 ID 无线传感器网络
CoAP 轻量级,适合受限设备,支持 M2M 通信和 HTTP 映射 边缘节点 M2M 通信
STOMP 基于文本,使用 HTTP 语义,语言兼容性好 消息导向中间件交互
AMQP 标准化,有负载均衡和排队机制,支持多语言客户端 大规模数据处理和消息队列场景

3.4 协议选择建议

在选择合适的 IoT 边缘到云协议时,需要考虑以下因素:
- 设备资源 :如果设备资源受限,如电池供电的传感器,CoAP 可能是更好的选择,因为它具有轻量级设计和低资源需求。
- 网络环境 :在无线网络中,MQTT - SN 可以利用其网关和主题 ID 机制来优化带宽使用。
- 应用需求 :如果需要负载均衡和正式的排队机制,AMQP 可能更适合;而如果只是简单的消息交互,STOMP 可能就足够了。

3.5 未来发展趋势

随着物联网的不断发展,这些协议也将不断演进和改进。例如,未来可能会有更多的安全机制集成到这些协议中,以满足日益增长的安全需求。同时,协议之间的互操作性也将变得更加重要,以便不同的设备和系统能够更好地协同工作。

总之,了解不同的 IoT 边缘到云协议的特点和适用场景,对于构建高效、可靠的物联网系统至关重要。开发者可以根据具体的需求选择合适的协议,并在实际应用中不断优化和改进。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值