我有一个通过发送和接收特定二进制数据包结构与之通信的设备。该设备有一个定义良好的API,但它可以返回100多种可能的消息类型。用于处理这些不同消息类型的好设计是什么?
这是伪代码的一个例子,我忽略了帧,校验和字节使它更清晰。
// I receive this message, where 0x00 indicates the device status,
//and each other byte is a particular error or status
message = [0x00, 0x01, 0x01, 0x04]
// The next message I receive, where 0x10 indicates system time,
// and the rest of the fields are the integer clock seconds of the device.
message = [0x10, 0x00, 0x32, 0xFF, 0x8E]
// 100 other message types....
正如您所看到的,我收到的每条消息都需要稍微不同的处理,具有不同的含义。我本来打算使用一个巨大的切换语句case 0x00: process_errors() case 0x10: process_time()
,但我很好奇是否有更好的设计,我可以用来增加添加新消息类型的灵活性,更好的可用性等。
您可以尝试使用TLV(标签长度值)实现。它有利于处理数据流。
标记 - 这将是一个数据字节(根据您的示例),它标识后面的消息类型。要使用它,您应该事先知道哪种消息类型有多少数据。例如,在0x00(设备状态)的情况下,您现在应该事先确定接下来的3个字节是数据。
长度 - 数据字节的长度
价值 - 实际数据
这是你可以做的: 1)准备系统支持的不同消息的标签和长度的映射。 2)连续接收数据字节。 3)读取第一个字节(这将是标签)并确定它是什么类型的消息。在你的情况下,这将给你0x00,0x10等。 4)请参阅您的标签和长度信息图。您将确定需要进一步读取的数据字节数。 5)读取数据部分后,接收器应准备好接收下一条消息(准备读取下一个标签)
这就是阅读消息。获得消息及其数据后,您可以随意使用它。例如,除了与Tag对应的消息长度之外,您还可以注册一个函数。这将允许您调用特定函数及其所需的参数。
设备状态
Data Tag = 00
Data Length = 03
Data Value = 01 01 04
系统时间
Data Tag = 10
Data Length = 04
Data Value = 00 32 FF 8E