iot/docs/message0305.md

7.5 KiB
Raw Blame History

交互流程数据格式说明

register

register的时候设备端向server.register发送注册信息,该信息格式如下:

{
	"c_id": "client_id",
	"r": "该客户端自己生成的公钥",
	"m": $object,
}

其中,c_id代表客户端本身的id用于唯一标识一个客户端r表示客户端自身的公钥该公钥用于与服务端交换aes密钥。

m是设备端的一些固有属性,目前结构如下:

{
	"cpu_core": 4, // 设备cpu核心数
	"memory": 1024, // 内存数MB
	"disk": 1024, // 硬盘容量GB
	"boot_time": 2000, // 启动时间
	"efka_version": "1.0.0", // 客户端版本
	"kernel_arch": "arm64", // 客户端硬件架构
	"province": "", // 所在省
	"city": "", // 所在市
	"adcode": 100, // 所在城市的编号
	"IPv4 1": "ip地址1",
	"IPv4 2": "ip地址2",
	...
}

在服务端在第一次收到该设备端的注册请求之后会先将该信息保存下来当用户在操作界面上对该设备进行授权之后服务端会生成一个AES密钥用该设备端的公钥进行加密然后向client.auth.$clientid写入授权信息客户端收到之后可以得到本身的授权情况。服务端用RSA公钥加密的结构如下

{
	"a": true/false, // 表示是授权还是拒绝授权
	"aes": "", // 如果a字段为true表示服务端允许授权该aes为一个加密字符串以后的通信服务端和设备端都使用该aes密钥进行加解密。
	"reply": "client.reply.$uuid" // 服务端设置的一个客户端回复的topic如果服务端在5秒之内没有回复就认为这个动作失败服务端就会反馈给操作界面的用户。
}

数据上传结构

设备端在采集到数据之后,会向server.data发送消息,消息格式如下:

{
	"c_id": "设备端ID",
	"d": $bytes
}

其中c_id是自身的clientidd代表具体的采集信息这部分数据通过与服务端交互商量的aes加密加密之前是一个列表列表里面的数据格式如下:

[
	{
		"client_id": "设备端ID",
		"service_name": "从该设备端的哪个服务采集的数据",
		"time": $time, // 采集时间unixnano的int64
		// 该微服务采集的数据是一个包含map的列表类型map的内容可以由微服务自己指定
		// 目前一般的格式是"metric-name": $value样式的数据
		"data": [
			{
				"name1": "test"
				"name2": 124,
				"name3": false
			}
		],
		// 微服务自身可以生成tag用于微服务指定自己的一些性质目前使用得不多以后可以扩展
		// 是一个map[string]string类型的数据
		"tag": {
			"tag1": "value1",
			"tag2", "value2"
		}
	}
]

命令下发结构

命令下发,用于服务端或者其他的系统,通过调用接口,向设备端发送消息,设备端会监听clients.cmd.$id的消息。

服务端在发送之前应先用该客户端的aes密钥进行加密将加密之后的二进制数据发送到该topic。

加密前的消息结构如下:

{	
	// 消息类型,目前支持四种消息类型:
	//  1代表参数下发就是向该设备端的微服务发送消息,该消息会辗转发送给微服务进行处理比如设置modbus微服务的波特率等消息
	//  2代表采集向下发比如设置某个设备短上的modbus微服务采集某个地址的数据
	//  3代表下发微服务文件。
	//  4代表下发数据流图这个指令用于设置设备端上各个微服务之间的逐句流转。
	"t": 1|2|3|4,
	// 针对不同的命令类型,这个字段里的`to`和`m`数据有所不同,具体在下面的小节描述
	"b": {
		// 任务id服务端在下发数据的时候需要生成一个唯一的uuid
		// 用于标识一个任务
		"t_id": "任务id",
		// 表示发给哪个微服务,这里是服务的标识,即服务名称
		"to":  "",
		// 命令执行的超时时间,单位为秒
		"t": 10,
		// 实际内容
		"m": $bytes
	}
}

下面介绍几种下发类型:

参数下发的结构

对于参数下发下发内容中的m为一个map[string]interface{}结构,用于向某个微服务发送参数,具体参数内容由微服务的参数配置提供。

采集项下发的结构

采集项下发时下发内容中的m为一个[]map[string]interface{}结构的列表,每一个条目是一个采集项内容,具体采集向内容由微服务的采集项配置提供。

微服务下发的结构

在微服务下发中,to字段会被忽略可以填写空字符串而m字段为json化之后的数据json化之前结构如下

{
	"f": "微服务名",
	"v": "微服务版本"
	"k": "微服务下载的token"
	"md5": "微服务的md5值用于验证下载完整性"
	// ms表示是微服务config表示配置文件self表示efka的新版本
	"t": "ms|config|self"
	// o代表oldversion老版本如果t为ms且o不为空字符串
	// 则表示要升级微服务版本,老版本的内容会被删除和替换。
	"o": "old-version"

}

ping结构

ping结构会上传到"server.ping", 结构体由msgpack格式编码, ping结构每隔20秒发送一次

{
	"c": "client_id",
	// 这个ping上传的时间
	"at": $int64,
	// 硬件信息目前有剩余内存剩余磁盘和cpu负载
	"h": {
		// 剩余内存单位为MB
		"fm": $int
		// 剩余磁盘单位为MB
		"fd": $int,
		// cpu负载是一个浮点数
		"cp": $float
	}
}

命令下发步骤上报结构

在任务下发之后,设备端会根据命令到哪个环节,进行步骤上报,上报的消息写入到server.step.feedback,上报结构如下:

{
	"c_id": "设备端id",
	"d": "aes加密后的二进制数据"
}

其中,d是具体数据经过aes加密后的二进制数据加密前的结构如下

{
	"t_id": "任务的task id",

	// sc为step code具体地
	//  0代表该任务开始了服务端创建该任务之后是这个代码
	//  1代表任务被分发了服务端向nats(mqtt)发送消息之后,是这个代码
	//  2代表任务被设备端接收到了
	//  3代表该任务已经被发送给微服务进行处理了
	//  4代表该任务已经被微服务收到了微服务正在处理
	//  5代表任务已经完成微服务已经处理完成。
	"sc": $int
}

有了这个步骤,最后任务超时等情况,就可以知道任务卡在哪里。

命令下发结果上报结构

任务在微服务处理完成之后,设备端会向服务端反馈任务执行的结果。该结果会写入server.result.feedback,上报的结构如下:

{
	"c_id": "设备端id",
	"d": "aes加密后的二进制数据"
}

其中,d是aes加密后的二进制数据加密前的结构如下

{
	"t_id": "任务id",
	// unix nano类型
	"t": $int,
	// 返回的结果码0代表成功其他代表出错
	"c": $int,
	"r": "任务执行的结果",
	"e": "错误消息当c为非0时这个字段会表示出错消息",
	// 返回任务类型1表示任务是微服务下发0代表是命令下发
	"t": 0 | 1,
}

inform结构

inform用于客户端主动通知服务端本地事情的发生比如自身的某个微服务下线了就会发送一个inform信息给服务端。

inform信息会发送给``, 结构如下:

{
	"c": "client_id",
	// 这个inform上传的时间
	"at": $int64,
	// 微服务信息
	"s": [{
		"n": "微服务名称",
		"v": "微服务版本",
		"c": "微服务副本",
		// 微服务是否在线0表示离线1表示在线
		"s": 0|1
	}]
}