Как обрабатывать много разных типов входных двоичных сообщений - PullRequest
0 голосов
/ 29 апреля 2019

У меня есть устройство, с которым я связываюсь, отправляя и получая конкретную структуру двоичного пакета.Устройство имеет несколько четко определенный 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....

Как видите, каждое полученное мной сообщение должно обрабатываться по-разному, иметь разные значения.Первоначально я собирался использовать гигантский оператор switch case 0x00: process_errors() case 0x10: process_time(), но мне было любопытно, есть ли лучший дизайн, который я мог бы использовать для повышения гибкости добавления новых типов сообщений, лучшей применимости и т. Д.

1 Ответ

1 голос
/ 30 апреля 2019

Вы можете попробовать использовать реализацию TLV (Tag Length Value). Это хорошо для обработки потока данных.

Tag - Это будет байт данных (согласно вашему примеру), который определяет тип сообщения, которое следует. Чтобы это можно было использовать, вы должны заранее знать, какой тип сообщения содержит сколько данных. Например, в случае 0x00 (состояние устройства) вы должны заранее указать, что следующие 3 байта являются данными.

Длина - Длина байтов данных

Значение - Фактические данные

Вот что вы можете сделать:
1) Подготовьте карту тега и длины различных сообщений, которые поддерживает ваша система.
2) Получать байты данных непрерывно.
3) Прочитайте 1-й байт (это будет тег) и определите тип сообщения. В вашем случае это даст вам 0x00, 0x10 и т. Д.
4) Обратитесь к вашей карте метки и информации о длине. Вы определите, сколько байтов данных вам нужно прочитать дальше.
5) Как только вы прочитаете часть данных, ваш получатель должен быть готов к получению следующего сообщения (готов к чтению следующего тега)

Это все о чтении сообщений. Когда у вас есть сообщение и его данные, вы можете использовать его по своему усмотрению. Например, помимо длины сообщения, соответствующего тегу, вы также можете зарегистрировать функцию. Это позволит вам вызывать определенную функцию вместе с требуемыми ей параметрами.

Состояние устройства

Data Tag = 00  
Data Length = 03  
Data Value =  01 01 04 

Системное время

Data Tag = 10  
Data Length = 04  
Data Value =  00 32 FF 8E  
...