首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >存储大小受限协议的前向兼容性

存储大小受限协议的前向兼容性
EN

Stack Overflow用户
提问于 2017-11-23 12:10:07
回答 2查看 85关注 0票数 2

我有一个简单的协议,包括4个字段:

代码语言:javascript
复制
Field-1 (4-bits)
Field-2 (6-bits)
Field-3 (4-bits)
Field-4 (2-bits)

目前,我将它们组织为字节对齐方式:

代码语言:javascript
复制
Field-1,Field-3,Field-2,Field-4

总之,该消息占用2个字节,开销为0字节。

为了使它向后兼容,因此我可以理解来自上一个版本的消息,我在开头添加了一个1字节版本字段,它变成:

代码语言:javascript
复制
Version-Field,Field-1,Field-3,Field-2,Field-4

总共3字节,开销为1字节。

如何添加前向兼容性,以便在新版本的协议中添加新字段,同时确保旧版本的软件仍然能够理解消息,并且开销尽可能低?

EN

回答 2

Stack Overflow用户

发布于 2017-12-10 19:02:54

通常,您的协议将指定每条消息具有:

  • 消息长度指示符,适用于所有未来版本。这通常是一个固定大小的整数,保证足够大,或者使用扩展位的可变长度编码整数,就像您在VLQ或UTF-8中看到的那样。
  • 解析消息所需了解的协议最低版本的指示符。这一点很重要,因为新版本可能会引入一些必须被理解的东西。

然后,协议的每一个新版本都允许您向符合协议前一版本的前缀中添加新数据,协议的每个版本都必须指定如何识别它定义的数据的末尾(在您的示例中,该数据的长度固定,因此很容易),以及在未来版本中定义的数据的开始。

要处理消息,使用者检查以确保它是一个足够高的版本,处理它所理解的前缀,并使用length字段跳过其余的。

对于像您的协议那样的空间限制,我可能会这样做:

  • 第一个字节是一个4位最小版本和一个4位长度字段.
  • 如果length字段L为0-11,则消息的其余部分为L+1字节长。
  • 否则,第一个字节后面的L-11字节是包含长度的整数.
  • 当您必须理解的最小版本> 15时,版本15之前的某个协议版本将在消息中定义其他版本信息。
票数 2
EN

Stack Overflow用户

发布于 2017-12-07 22:21:00

通过确保严格遵守此规则,您将拥有FC:

新版本必须使以前的版本知道字段布局。

如果您能够遵循规则,您将自动拥有BC和FC。因此,使用该规则,您只能通过将新字段附加到现有布局中来添加它们。

让我举个例子来解释。假设您需要为版本2添加这些字段:

代码语言:javascript
复制
Field-5 (1-bit)
Field-6 (7-bits)

记住,新字段只能附加到现有布局中。因此,这是version 2消息布局:

代码语言:javascript
复制
Version-Field,Field-1,Field-3,Field-2,Field-4,Field-5,Field-6

因为版本1已知的布局是完整的,所以版本1代码可以读取任何版本的消息(伪代码):

代码语言:javascript
复制
function readMessageVersion1(byte[] input) {
    var msg = {};
    msg.version = input[0];

    msg.field1 = input[1] & 0x0f;
    msg.field3 = input[1] >> 4 & 0x0f;

    msg.field2 = input[2] & 0x3f;
    msg.field4 = input[2] >> 6 & 0x03;

    return msg;
}

Version 1不需要检查version字段,因为已知的布局是无条件的。但是,version 2和所有其他版本都需要检查version字段。假设我们使用值2来指示版本2,这就可以了(伪代码):

代码语言:javascript
复制
function readMessageVersion2(byte[] input) {
    var msg = readMessageVersion1(input);

    //check version field
    if (msg.version < 2) return msg;

    msg.field5 = input[3] & 0x01;
    msg.field6 = input[3] >> 1 & 0x7f;

    return msg;
}

代码最重要的部分是它重用了以前版本的代码和这个检查:

代码语言:javascript
复制
if (msg.version < 2) return msg;

代码的第3版可以简单地跟随版本2,如下所示:

代码语言:javascript
复制
function readMessageVersion3(byte[] input) {
    var msg = readMessageVersion2(input);

    //check version field
    if (msg.version < 3) return msg;

    // read the input bytes here

    return msg;
}

将其视为未来版本的模板。通过遵循规则和示例,任何版本的协议都可以读取来自任何版本的消息,仅需1字节开销。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47455284

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档