目录
一、chirpstack介绍
二、网关与chirpstack之间的通信
三、NS与AS之间的通信
1、Protobuf
2、gRPC
ChirpStack 是一个开源的 LoRaWAN 网络服务器,可用于 设置私有或公共 LoRaWAN 网络。ChirpStack 提供了一个 Web 界面 用于管理网关、设备和应用程序。ChirpStack 还提供了一个基于 gRPC 的 API,可以 用于集成或扩展 ChirpStack。我是在 Linux下 使用 Docker 进行搭建chirpstack 服务器,不熟悉的朋友可以看《在Linux下使用Docker部署chirpstack》。本篇文章主要讲解chirpstack中的内容。
chirpstack由以下几部分组成:
(1)ChirpStack Network Server: 简称NS,作用是确保 LoRaWAN 网络的正常运行和管理设备通信。其负责 LoRaWAN 网络的核心逻辑。它处理设备的加入过程、下行链路调度、设备活动状态跟踪等。它还负责处理从 LoRa 网关接收到的上行数据,并将下行数据发送到网关。
(2)ChirpStack Application Server: 简称AS,作用是管理和处理应用层数据,提供用户界面和 API 接口。其负责处理和管理 LoRaWAN 应用层数据。它允许用户定义应用程序、设备配置和数据解码器。它还提供 API 和 Web 界面,用于管理设备、监控网络流量、处理数据解码和发送应用层数据到外部应用程序。
(3)ChirpStack Gateway Bridge:它充当网关和网络服务器之间的中间件。该组件可以将LoRa网关传输来的LoRa数据包转发器协议转换成ChirpStack网络服务器通用的数据格式(JSON等)。
(4)PostgreSQL:这是一个开源的关系型数据库管理系统,用于持续化存储 ChirpStack 的配置数据、设备信息、网关信息、应用程序数据等。
(5)Redis:这是一个开源的内存中数据结构存储系统,通常用作数据库、缓存和消息代理。ChirpStack 使用 Redis 来缓存和处理一些实时数据,提高系统性能和响应速度。
(6)Mosquitto:Mosquitto是一个MQTT协议的代理服务器,用于处理设备和ChirpStack组件之间的通信。它允许LoRaWAN网关和ChirpStack服务之间的消息传递。
我们先来看一下LoRaWAN网络的通信架构:
LoRaWAN网络大体上规定了一个这样的架构:终端节点、网关、服务器(NS、AS)。我们需要注意一下。在这个架构中,各个部分之间并不都是通过 LoRaWAN协议 进行通信的。终端节点与网关之间走的是标准的LoRaWAN协议,使用LoRa调制技术在无线电频段发送封装好的数据包。这些数据包由网关接收,通常采用 UDP协议 将数据转发至相应的服务器。
网关收到数据后,并不是直接把数据转发至服务器。网关会对有效负载 payload 进行 base64 编码。然后,再添加对应的元数据(如信号强度、信噪比等)。刚刚已经提到过网关和服务器之间是采取UDP协议进行通信的。显然,网关收到的数据包不进行处理肯定是无法传输的,这就需要介绍一下Semtech UDP Packet Forwarder(Semtech UDP 格式转换器)了。Semtech UDP 格式转换器用于将 LoRaWAN 数据转换成标准的 UDP 数据包格式。
前面我们提到了chirpstack的几个组件,我们可以看出来,在网关发送消息给服务器首先发给的是网关桥(如果网关桥安在了网关上则直接发给MQTT代理器)。网关桥起到了怎么一个角色呢?网关桥会解析传来的数据,并封装成标准的消息格式(如JSON或自定义格式),通过MQTT协议,经MQTT代理器转发至网络服务器NS。
Protobuf 是一种数据交换格式,相对于XML、JSON,有着属于自己独特的优势。在了解NS与AS之间的数据传输,就一定要了解这种数据格式。Protobuf 是一种结构化数据的序列化方法,提供了高效率的序列化和反序列化机制,序列化就是把对象转换成二进制数据发送给服务端,反序列化就是将收到的二进制数据转换成对应的对象。
大家比较熟悉的应该是JSON吧,那我们来对比一下Protobuf 和 JSON 吧!
我们先来看看JSON的格式:
{ "int":12345, "str": "hello", "bool": true }
JSON主要有两个缺点:一是非字符串的编码低效。比如说12345,在内存中只占两个字节,但是转成JSON格式却要占五个字节;二是信息冗余,同一个接口同一个对象,只是 int 字段的值不同,每次都还要传输“int”这个字段名。
但是JSON有着很好的可读性,易于人阅读和编写,这也是JSON为什么编码效率较低但依然广受欢迎的原因。
我们再来看一下Protobuf的格式:
message Demo { int32 i = 1; string s = 2; bool b = 3; }
Protobuf选用了Varlnts对数字进行编码,解决了效率问题。另外给每一个字段指定一个整数编号,传输的时候只传字段编号,解决了冗余问题。
但是,使用Protobuf数据交换格式,就必须要求通信双方事先约定好各个编号分别对应哪个字段。通过使用特定的编译器将.proto 文件转换为各种编程语言的源代码,以便开发人员在各种语言中使用Protobuf。在.proto文件中使用的是接口定义语言(IDL),通过编写接口定义语言,可以定义如何通过不同的进程或模块进行通信,并定义如何序列化和反序列化数据。因为其独特的特性,gRPC 默认选用Protobuf。
chirpstack 的网络服务器NS 和应用服务器AS 就是通过gRPC来通信的。gRPC 是 谷歌研发的一套RPC协议框架。RPC框架的目标就是让远程服务调用更加简单,服务调用者可以像调用本地接口一样调用远程的服务提供者。
gRPC 使用http2 作为网络传输层,使用 protobuf 这个高性能的数据包序列化协议。