• 结构体作为接口的注意事项


    在后端向前端回复数据时,需要将结构化数据通过网络传输给前端,而网络传输是字节流传输,前端收到的是一段数据,那么,问题就落脚在如何解析这段数据。

    很多请求的场景,返回的条数是动态变化的,比如订单数量。用户每下一个订单,那么请求返回的数量就会加1.这时候,如何较好的返回动态数据呢?这个看使用怎样的存储格式来承载可变长度的数据返回。就目前已知的处理方法:

    • 使用 json 格式
    • 使用 protobuf 格式
    • 使用 struct 格式

    由于工作需要,这里使用 struct 格式来进行数据的包裹。

    固定长度的返回数据

    比如,查询某个用户的账户余额,返回的结构体类似如下:

    struct TAccountCapital : struct PacketHead
    {
    	double m_dCapital;
    }
    
    

    struct PacketHead为包头结构体,里面的内容为传输过程中的一些通用选项,在此不表。

    当该结构体后续有扩展时,只要保证后续新增的字段始终放在后面,那就可以保持升级后新旧版本的兼容性。

    可变长度的返回数据

    比如,查询某个用户的当日订单信息,返回的结构体类似如下:

    
    struct TAccountOrder :struct PacketHead
    {
    	int m_nCount;	// 订单个数
    	TOrderInfo  m_OrderInfo[1];	 // 订单数据
    }
    
    struct TOrderInfo
    {
    	int m_nOrderNo;	 			 // 订单编号
        string m_nOrderProductName;	 // 订单商品名称
    }
    
    

    这里用到的 linux下的 零长数组技巧,此处不再赘述。

    客户端在接收到此类数据时,先通过 sizeof(TOrderInfo) * m_nCount得到订单数据的真实长度,然后以sizeof(TOrderInfo)为步长,将内存中数据整理输出,显示出来。

    到这一步,看起来都很美好。

    再往下看,随着业务的发展,订单信息需要新增一个字段,比如新增订单折扣信息。此时的返回结构体如下:

    
    struct TOrderInfo
    {
    	int m_nOrderNo;	 			 // 订单编号
        string m_nOrderProductName;	 // 订单商品名称
    	double m_dOrderDiscount;	 // 订单折扣信息
    }
    
    

    一旦结构体有所改变,就存在前后端面对的结构体不一致,如果前端还按照原有的步长来截取内存输出,随后的订单信息就会全部错乱。

    造成这个问题的原因是前端使用的结构体与后台的不一致,后台的修改带来了兼容性问题。既然问题根源知道了,那么解决的方法也有浮出水面了。那就是让前端知道真正的步长,这个步长不能依赖于前端能够看到的结构体长度,而要通过其他途径了解真实的长度,而这个真实的长度,只有后台了解,因此,需要后台增加一个字段,表示传递结构体真正的长度。

    
    struct TAccountOrder :struct PacketHead
    {
    	int m_nCount;				 // 订单个数
    	int m_nItemSize;			 // 订单数据结构体大小
    	TOrderInfo  m_OrderInfo[1];	 // 订单数据
    }
    
    

    结论

    在使用结构体传递可变数据时,使用零长数组传输数据时,需要增加返回的结构体大小成员。

    同时,要同前端开发人员做好约定,在解析数据时,要依赖接口中的结构体大小成员,而不要依赖自己算出来的结构体成员大小。

  • 相关阅读:
    IOS 开发 网络发展史(基础知识)
    加密详解
    IOS对接支付的流程
    App混合开发浅谈
    swift语法100
    2015年最新Android基础入门教程目录第二章:Android UI(User Interface)详解(已完结 40/40)
    2015年最新Android基础入门教程目录第一章:环境搭建与开发相关(已完结 10/10)
    Reactive开发
    tensorflow 安装
    Mask RCNN笔记
  • 原文地址:https://www.cnblogs.com/cherishui/p/10340845.html
Copyright © 2020-2023  润新知