• 关于C#调用protobuf 序列化和反序列化


    前段时间公司需要跟百度聚屏联调,他们的接口数据都是通过protobuf封装的;

    为此,我废了好大的脑子,毕竟开局一个文档(参数名和实际给我的参数名都不一致),剩下全靠摸索;

    弄懂了之后,其实也没这么复杂。一开始我用proto 3.0.0 和 3.6.1版本封装,不行,因为对方接口要求版本2.X;

    在Google搜到发现貌似protobuf早期版本不支持C#,所以蛋蛋很是忧伤;后来找到一个proto-net版,编译后请求还是不行;

    历经几天苦逼的摸索,下面直接给代码

    proto文件:

    package Test;
    
    /*
        聚屏媒体接入api文档,接口版本: 6.0.0
    */
    
    
    
    
       // 操作系统类型
       enum OsType {
        UNKNOWN = 0;
        ANDROID = 1;  // Android
        IOS = 2;  // iOS
        WINDOWS = 3;
    };
    
    // 版本号信息
    message Version {
        optional uint32 major = 1[default = 0]; // 必填!
        optional uint32 minor = 2[default = 0]; // 选填!
        optional uint32 micro = 3[default = 0]; // 选填!
    };
    
    // 唯一用户标识,必需使用明文,必需按要求填写,具体填写指导详见接口说明文档
    enum UdIdType {
    
        MAC = 1; // 设备的WiFi网卡MAC地址,字母大写,格式要求[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}
        MEDIA_ID = 2; //媒体内部维护的唯一Id,仅对少部分媒体开放,默认仅允许mac id
    }
    message UdId {
        optional UdIdType id_type = 1; //必填! id 类型,默认仅允许mac
        optional bytes id = 2; //必填!
    };
    
    // 二维尺寸信息
    message Size {
        optional uint32 width = 1[default = 0];  // 必填!宽度 单位是像素
        optional uint32 height = 2[default = 0];  // 必填!高度 单位是像素
    };
    
    message Device {
        optional UdId udid = 1;  // 必填!唯一设备标识,必需按要求填写
        optional OsType os_type = 2;  // 必填!操作系统类型
        optional Version os_version = 3;  // 必填!操作系统版本
        optional bytes vendor = 4[default = ""];  // 必填!设备厂商名称,中文需要UTF-8编码
        optional bytes model = 5[default = ""];  // 必填!设备型号,中文需要UTF-8编码
        optional Size screen_size = 6; // 必填!设备屏幕宽高
    }
    
    // WiFi热点信息
    message WiFiAp {
        optional bytes ap_mac = 1;  // 必填!热点MAC地址,格式要求[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}
        optional int32 rssi = 2;  // 必填!热点信号强度,通常是负数
        optional bytes ap_name = 3;  // 必填!热点名称,可不传递,建议传递当前接入热点的名称,用于判断用户当前所处场所,中文需要UTF-8编码
    };
    
    // GPS信息
    message Gps {
        // GPS坐标类型
        enum CoordinateType {
            WGS84 = 1;  // 全球卫星定位系统坐标系
            GCJ02 = 2;  // 国家测绘局坐标系
            BD09 = 3;  // 百度坐标系
        };
        optional CoordinateType coordinate_type = 1;  // 必填!坐标类型
        optional double longitude = 2;  // 必填!经度
        optional double latitude = 3;  // 必填!纬度
    };
    
    // 网络环境信息
    message Network {
        // 网络连接类型
        enum ConnectionType {
            UNKNOWN_NETWORK = 0;
            WIFI = 1;
            MOBILE_2G = 2;
            MOBILE_3G = 3;
            MOBILE_4G = 4;
            ETHERNET = 101; // 以太网接入
            NEW_TYPE = 999;  // 未知新类型
        };
    
        // 运营商代号,每个运营商唯一(PLMN码每个运营商可能有多个)
        enum OperatorType {
            ISP_UNKNOWN         = 0;  //未知运营商
            ISP_CHINA_MOBILE    = 1;  //中国移动
            ISP_CHINA_UNICOM    = 2;  //中国联通
            ISP_CHINA_TELECOM   = 3;  //中国电信
            ISP_FOREIGN         = 254; //其它运营商
        }
        optional bytes ipv4 = 1;  // 必填!用户设备的公网IPv4地址,服务器对接必填,格式要求:255.255.255.255
        optional ConnectionType connection_type = 2;  // 必填!网络连接类型,用于判断网速
        optional OperatorType operator_type = 3;  // 必填!移动运营商类型,用于运营商定向广告
    };
    
    //物料类型
    enum MaterialType {
        VIDEO = 1;
        IMAGE = 2;
    }
    
    //媒体的用户特征数据
    message UserInfo {
        optional bytes media_channel = 1; //选填! 电视频道、公交路线等。需预先和百度确定映射关系
        repeated bytes tags = 2; //选填! 当前设备用户画像。需预先和百度确定映射关系
        repeated bytes phone_numbers = 3; //选填! 当前设备用户手机号当前设备用户手机号。加密规则预先约定,需支持反解
        repeated bytes browse = 4; // 选填! 当前设备历史流量信息。需预先和百度确定映射关系
    }
    
    //设备探针数据
    message ProbeInfo {
        optional bytes client_mac = 1; //必填! 探测设备mac
        optional int32 client_rssi = 2; //必填! 探测设备热点强度
    }
    
    message SlotInfo {
        required bytes adslot_id = 1; // 必填! 广告位id 平台生成
        optional uint32 base_price = 2; //选填! [仅百度内部流量可用,其它流量暂时不允许填充]
        optional uint32 multi_show = 3; //选填! [仅百度内部流量可用, 其它流量暂时不允许填充]
    }
    
    message TsApiRequest {
        //1.基础参数
        required bytes request_id = 1; //必填!   接入方自定义请求ID [仅英文字母和数字, 32位]
        required Version api_version = 2;  // 必填!API版本,按照当前接入所参照的API文档版本赋值,影响所有后续逻辑,填写错误会导致拒绝请求。
    
        //2. 媒体参数
        required bytes app_id = 3; //必填! 标识资源方,平台生成
    
        //3. 广告位参数
        required SlotInfo slot = 4; //必填! 广告位信息
    
        //4. 设备参数
        optional Device device = 5; //必填! 设备信息
    
        //5. 网络参数
        optional Network network = 6;  // 必填!网络环境信息
    
        //6. wifi ap参数
        optional WiFiAp wifi_ap = 7;  // 选填!连接的wifi热点参数, OTT强烈建议填写
    
        //7. 探针参数 或者 通过路由表等方式获取到的周边设备MAC地址
        repeated ProbeInfo prob_infos = 8; //选填! 设备探针数据,强烈建议填写
    
        //8.GPS 参数
        optional Gps gps = 9;  // 选填!GPS定位信息,用于辅助触发LBS广告
    
        //9. 用户参数
        optional UserInfo user_info = 10; //选填! 建议尽可能提供更多的用户信息,提升变现能力
    
        repeated WiFiAp scan_wifi_ap = 11;  // 选填!扫描到的wifi热点参数, OTT强烈建议填写
    }
    
    // 广告物料元数据信息
    message MaterialMeta {
        optional MaterialType material_type = 1; //物料类型 图片,视频
        optional bytes click_url = 2;  // 点击行为地址,用户点击后,在客户端进行响应,会经过多次302跳转最终到达目标地址
        repeated bytes icon_src = 5;  // 广告图标地址,注意:单个广告可能有多张图标返回
        repeated bytes image_src = 6;  // 广告图片地址,注意:单个广告可能有多张图片返回
        optional bytes video_url = 7;  // 广告视频物料地址
        optional uint32 video_duration = 8;  // 广告视频物料时长
        optional uint32 material_width = 9;  // 物料的宽度:如果是图片,表示图片的宽度;如果是视频(含有视频截图),则为视频宽度;如果是图文或文本,则不会填充此字段
        optional uint32 material_height = 10;  // 物料的高度:如果是图片,表示图片的高度;如果是视频(含有视频截图),则为视频高度;如果是图文或文本,则不会填充此字段
        optional uint32 material_size = 11; // 图片、视频物料大小,单位kb
        optional bytes material_md5 = 12; // 图片,视频物料的md5值
    };
    
    // 广告效果跟踪信息
    message Tracking {
        // 广告展示过程事件类型
        enum TrackingEvent {
            // 视频类广告展示过程事件
            VIDEO_AD_START = 1;  // 视频开始播放
            VIDEO_AD_FULL_SCREEN = 2;  // 视频全屏
            VIDEO_AD_END = 3;  // 视频正常播放结束
            VIDEO_AD_START_CARD_CLICK = 4;  // 点击预览图播放视频
        };
        optional TrackingEvent tracking_event = 1;  // 被跟踪的广告展示过程事件
        repeated bytes tracking_url = 2;  // 事件监控URL
    };
    
    message Ad {
        optional bytes title = 1; //广告标题,utf-8 编码
        optional bytes brand_name = 2; //广告品牌名,utf-8 编码
        optional bytes description = 3; //广告描述,utf-8编码
        optional bytes icon_url = 4; // 广告主品牌logo
        repeated MaterialMeta material_metas = 5; //物料的元数据
        repeated bytes win_notice_url = 6;  // 曝光日志URL列表,在曝光后必须在客户端逐个汇报完
        repeated Tracking ad_tracking = 7;  // 广告监控信息(预留接口,媒体暂时不需要关注)
        repeated bytes third_monitor_url = 8 ; //广告主监控请求,在曝光后必须在客户端端逐个汇报完
        optional bytes ad_key = 9;  //广告唯一标识id
    }
    
    message TsApiResponse {
        //1.0 基础参数
        required bytes request_id = 1;  // 对应请求的接入方自定义请求ID
        required uint64 error_code = 2;  // 请求响应出错时的错误码,用于问题排查
        optional bytes adslot_id = 3;  // 对应请求时填写的广告位ID
        // 广告清单
        repeated Ad ads = 4;  // 应答广告清单,一次请求可以返回多个广告,需要逐个解析
        optional uint32 expiration_time = 5;  // 广告清单过期时间戳,单位秒
        optional bytes search_key = 6; // 当次请求百度生成的唯一表示ID
        //广告logo标识
        optional bytes jp_adtext = 7; //新广告法出台,要求明确使用"广告",该字段为"广告"小图标地址,媒体需要在渲染的时候添加
        optional bytes jp_adlogo = 8; //新广告法出台,该字段为与上述字段配合使用的"熊掌"图标地址,媒体需要在渲染的时候添加
    }

    序列化和反序列化

      data da = new data();
    
                using (var fs = File.Create("D:\da.bin"))//文件输出流
                {
                    Serializer.Serialize<data>(fs, da);//把user对象序列化出二进制文件放入fs文件里面
                }
                data da1 = null;
                using (var fs = File.OpenRead("D:\da.bin"))
                {
                    da1 = Serializer.Deserialize<data>(fs);//反序列化
                }
                Console.WriteLine("request_id:" + da1.request_id + ",app_id:" + da1.app_id + "");

    上面的proto文件通过下面文件编译即可-貌似不能直接上传文件,你们自己百度去吧,找不到就留言

    推荐几个地址:https://www.cnblogs.com/Leo_wl/p/7126321.html

    http://www.cnblogs.com/liuxiaoji/p/9517635.html

    https://www.jianshu.com/p/f2e8846a296d

  • 相关阅读:
    jsADS的库(待更新)
    javascript设计模式工厂方法模式
    jQuery星级评价
    邮政编码联动地址
    ADS图像缩放与剪裁(只是完成了前台的功能,传送数据到后台的功能待完成)
    ie6png透明解决(ietester的ie6有问题,原生ie6是没问题的)
    javascript设计模式桥接模式
    每一个人都应该学会执着
    防止电脑被攻击
    获取用户的IP地址的三个属性的区别
  • 原文地址:https://www.cnblogs.com/94LH-shuai/p/10103725.html
Copyright © 2020-2023  润新知