自动化系统中的消息数据包管理

在自动化系统中,与各种设备进行通信是至关重要的。这些通信协议通常由基于字符串或结构的数据包组成。虽然基于结构的数据包更容易解析其内容,并且可以比基于字符串的数据包更小,但由于基于字符串的数据包在异构系统中具有更好的兼容性,因此在通信系统中经常使用基于字符串的数据包。本文介绍了一种具有解析和队列功能的消息数据包管理器。

消息格式

将记录定义为数据包的单位,记录包含多个字段。例如,可以将基于结构的数据包转换为基于字符串的数据包,如下所示:

struct EQP_Cleaner { char ID[5]; RGB color; int part_number; int duration; }

转换为基于字符串的数据包:

<EQP_CLEANER ID=EQP01 color=RED part_number=80 duration=100/>

使用代码

可以通过简单的代码定义消息格式,并使用以下方法来设置队列和处理数据:

  • clear(..) - 清空队列
  • setQsize(..) - 设置队列大小
  • pushMessage(..) - 将消息推送到队列
  • popMessage(..) - 从队列中弹出消息

定义

消息数据包描述了由记录名称和字段集组成的记录。记录和字段的结构如下:

public class Field { public String name; public String value; } public class Record { public String name; ArrayList<Field> Fields = new ArrayList<Field>(); public int size() { return Fields.size(); } }

功能描述

以下是一些关键方法的描述:

void setQsize(int size) - 设置缓冲区存储消息数据包的最大大小 int size() - 获取当前缓冲区存储的消息数据包数量 void clear() - 清空缓冲区 void addField(Record t, Field f) - 向记录添加字段 void addRecord(Record t) - 向缓冲区添加记录 Record getRecord(int index) - 通过索引获取缓冲区中的记录 Record getRecord(String name) - 通过名称关键字获取记录 Field getField(Record t, int index) - 获取指定记录中的字段 Field getField(Record t, String name) - 通过名称关键字获取指定记录中的字段 Record deleteMessage(int index) - 删除指定索引的记录 Record deleteMessage(String name) - 通过名称关键字删除记录 Record popMessage() - 获取并删除缓冲区中最旧的记录 void pushMessage(String strLine) - 将记录插入缓冲区,记录将通过解析字符串消息填充。如果当前缓冲区大小大于最大存储大小,将删除最旧的记录。

实现

pushMessage(..) 方法同时实现了解析字符串消息并将其推送到缓冲区存储的功能。

public void pushMessage(String strLine){ int bracket_start=0; if (strLine.isEmpty() == false) { if (size() >= mQsize) { Record t = tags.get(0); t.Fields.clear(); tags.remove(0); } String bracketName=null; String bracketValue=null; do { int start = 0; int end = 0; start = strLine.indexOf("<", bracket_start); if (start<0) break; end = strLine.indexOf("/>", start); if (end<0) break; String tmp = strLine.substring(start+1, end); bracket_start = end; start = 0; end = tmp.indexOf(" ", start); if (end<0) continue; bracketName = tmp.substring(start, end); bracketValue = tmp.substring(end+1, bracket_start-1); } while (bracket_start>=0); if (bracketValue!=null) { String org = bracketValue; Record t = new Record(); t.name = bracketName; int index=0; while (index < org.length()) { Field f = new Field(); index = getField(org, index, f); addField(t,f); } addRecord(t); } } }

使用

首先,需要创建 MessageManager 的对象:

MessageManager msgManager = new MessageManager();

然后通过 pushMessage(..) 填充缓冲区:

msgManager.pushMessage(strMsg);

根据需求,可以调用 popMessage(..):

record = msgManager.popMessage();

如果调用了 popMessage,最终可以使用返回的记录获取想要的字段:

field = msgManager.getField(record,index);

如果想要初始化缓冲区,可以调用 clear():

msgManager.clear();

示例

以下是使用 MessageManager 的一个示例:

public static void main(String[] args) { int buffsize = 6; MessageManager.Record record = null; MessageManager.Field field = null; String strMsg1 = ""; String strMsg2 = ""; String strMsg3 = ""; String strMsg4 = ""; String strMsg5 = ""; String strMsg6 = ""; String strMsg7 = ""; MessageManager msgManager = new MessageManager(); msgManager.clear(); System.out.println("Add the buffer by strMsg1,strMsg2,...,strMsg5, buffer size:" + buffsize); msgManager.setQsize(buffsize); msgManager.pushMessage(strMsg1); msgManager.pushMessage(strMsg2); msgManager.pushMessage(strMsg3); msgManager.pushMessage(strMsg4); msgManager.pushMessage(strMsg5); msgManager.pushMessage(strMsg6); msgManager.pushMessage(strMsg7); System.out.print("Print buffer--------------------------------------"); for (int i = 0; i < msgManager.size(); i++) { record = msgManager.getRecord(i); System.out.print("\n" + record.name + ":"); for (int j = 0; j < record.size(); j++) { field = msgManager.getField(record, j); if (field != null) System.out.print("(" + field.name + ")" + field.value); } } System.out.print("\nPop message-------------------------------------"); record = msgManager.popMessage(); System.out.print("\n" + record.name + ":"); for (int k = 0; k < record.size(); k++) { field = msgManager.getField(record, k); if (field != null) System.out.print("(" + field.name + ")" + field.value); } System.out.print("\nbuffer after pop-------------------------------"); for (int i = 0; i < msgManager.size(); i++) { record = msgManager.getRecord(i); System.out.print("\n" + record.name + ":"); for (int j = 0; j < record.size(); j++) { field = msgManager.getField(record, j); if (field != null) System.out.print("(" + field.name + ")" + field.value); } } System.out.print("\nFind MsgId5 and it's field3---------------------"); record = msgManager.getRecord("MsgId5"); if (record != null) { System.out.print("\n" + record.name + ":"); field = msgManager.getField(record, "field3"); } else { System.out.println("\ncannot find record.."); field = null; } if (field != null) System.out.print("(" + field.name + ")" + field.value); else System.out.println("\ncannot find field.."); msgManager.deleteMessage("MsgId6"); System.out.print("\nbuffer after Delete MsgId6 Message-------------"); for (int i = 0; i < msgManager.size(); i++) { record = msgManager.getRecord(i); System.out.print("\n" + record.name + ":"); for (int j = 0; j < record.size(); j++) { field = msgManager.getField(record, j); if (field != null) System.out.print("(" + field.name + ")" + field.value); } } }

结果

可以按照以下指令编译并运行:

  • 确保环境支持 Java 编程语言。
  • 将上述代码保存为一个 .java 文件。
  • 使用 Java 编译器编译该文件。
  • 运行编译后的程序。
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485