当前位置: 首页 > news >正文

网站建设技术风险分析18款app软件免费下载百度

网站建设技术风险分析,18款app软件免费下载百度,汕头论坛网,seo需要什么技术2019独角兽企业重金招聘Python工程师标准 ---恢复内容开始--- 最近编写一个游戏用到protobuf数据格式进行前后台传输#xff0c;苦于protobuf接受客户端的数据时是需要数据类型的如xxx.parseForm(...),这样就要求服务器在接受客户端请求时必须知道客户端传递的数… 2019独角兽企业重金招聘Python工程师标准 ---恢复内容开始--- 最近编写一个游戏用到protobuf数据格式进行前后台传输苦于protobuf接受客户端的数据时是需要数据类型的如xxx.parseForm(...),这样就要求服务器在接受客户端请求时必须知道客户端传递的数据类型。由于客户端的请求数据是多种多样的服务器端又不知道客户端的请求到底是哪个类型这样就使得服务器端编程带来很多麻烦甚至寸步难行。难道就没有解决办法了吗答案当然是有的。下面就说一下常用的方法。在看本文之前建议先了解protobuf的一些基本语法和基本用法 1.第一种方法也是最简单的方法就是在整个应用程序中只定义一个proto文件那么所有的请求都是一种类型那么服务器端就不用苦恼怎么解析请求数据了因为不管哪个请求数据都用同一个对象解析。如下面的列子 首先贴一个PBMessage.proto文件 //客户端请求以及服务端响应数据协议 option java_outer_classname PBMessageProto; package com.ppsea.message; import main/resources/message/DataMsg.proto; message PBMessage{ optional int32 playerId 1; //玩家id required int32 actionCode 2; //操作码id optional bytes data 5; //提交或响应的数据 optional DataMsg dataMsg 6; //服务器端推送数据 optional string sessionKey 7; //请求的校验码 optional int32 sessionId 8;//当前请求的标示 } 如上述代码整个应用都基于PBMessage.proto传输注意到protobuf 语法中 optional修饰符他表示这个字段是非必须的也就是说对于客户端的不同请求只需要为它填充其请求时用到的字段的值即可其他的字段的值就不用管了这样就可以模拟出各种请求来那么接下来我们就用: PBMessage.parseForm(byte_PBMesage) // byte_PBMesage表示客户端请求数据 ,这样请求的解析就完成了。同时我们注意到 required int32 actionCode 2; // 操作码id required表示该字段是必须的前面请求已经解析好了在这里我们拿到 actionCode 就可以知道我们该用哪个Action事件来处理该请求了前提是必须维护一张actionCode到Action的映射关系表Mapint,Action至此整个请求的解析和处理都完成了。 接下来说一下第一种方式的优缺点优点整个应用消息格式一致统一操作简单。缺点太统一就不灵活对于请求很少消息格式很少的小型应用倒还勉强能用消息格式多的话再用这种方式就显得臃肿不便于管理失去了程序设计的意义。 2.第二种方法也是我本次用到的方法。苦于提议中方式的局限性本人通过在网上收集资料以及查看protobuf java版的源码发现了一个折中的方式。首先我们看下protobuf源码中提供的 DynamicMessage 类顾名思义 动态消息类眼前一亮有木有它继承了AbstractMessage类比较一下和第一种方式创建的PBMessage类的区别 我们发现PBMessage类继承了GeneratedMessage类而GeneratedMessage类继承了AbstractMessage类至此我们发现了共同类AbstractMessage再次证明了DynamicMessage 管用同时我们再看看AbstractParserMessageType类在PBMessage类中持有AbstractParser类的对象并用其来解析请求数据,它继承了ParserMessageType接口看看其部分方法 public abstract MessageType parseFrom(byte[] paramArrayOfByte) throws InvalidProtocolBufferException; public abstract MessageType parseFrom(InputStream paramInputStream) throws InvalidProtocolBufferException; public abstract MessageType parseFrom(InputStream paramInputStream,ExtensionRegistryLite paramExtensionRegistryLite) throws InvalidProtocolBufferException; 再看看DynamicMessage 里面提供的方法 public static DynamicMessage parseFrom(Descriptors.Descriptor type,byte[] data) throws InvalidProtocolBufferException { return ((Builder) newBuilder(type).mergeFrom(data)).buildParsed(); } public static DynamicMessage parseFrom(Descriptors.Descriptor type,byte[] data, ExtensionRegistry extensionRegistry)throws InvalidProtocolBufferException { return ((Builder) newBuilder(type).mergeFrom(data, extensionRegistry)).buildParsed(); } public static DynamicMessage parseFrom(Descriptors.Descriptor type,InputStream input) throws IOException { return ((Builder) newBuilder(type).mergeFrom(input)).buildParsed(); } public static DynamicMessage parseFrom(Descriptors.Descriptor type,InputStream input, ExtensionRegistry extensionRegistry)throws IOException { return ((Builder) newBuilder(type).mergeFrom(input, extensionRegistry)).buildParsed(); } 发现了他们方法的相似点在这里我们可以用一个等量关系比喻DynamicMessageAbstractMessage AbstractParserPBMessage也就是说DynamicMessage继承AbstractMessage请求消息对象的同时又间接实现了AbstractParser请求消息数据解析对数据解析的功能。现在我们唯一缺少的就是 Descriptors.Descriptor对消息的描述对象这个对象该怎么拿到呢在这里肯定的说对于不同的.proto请求这里的Descriptors.Descriptor是不一样的。在这里我们又回到PBMessage对象中我们发现了其中有这样一个方法 public final class PBMessageProto { ..................//此处省略若干行public static final class PBMessage extendscom.google.protobuf.GeneratedMessage implements PBMessageOrBuilder {...........//此处省略若干行 public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { return com.ppsea.message.PBMessageProto.internal_static_com_ppsea_message_PBMessage_descriptor; } } } 这不就是我们苦苦寻找的东西吗通过这个方法就可以拿到Descriptor了不是吗。在这里重点来了再来理解一下首先有了 PBMessage对象这里用其来做代表可以使其他的.proto对象就可以获得 Descriptors.Descriptor 对象有了Descriptors.Descriptor对象就可以创建DynamicMessage对象了有了DynamicMessage就可以解析对应请求了。下面看代码 //存放消息操作码和消息对象 MapInteger,Descriptor descriptorMapnew MapInteger,Descriptor; //把消息描述对象添加进来 descriptorMap.add(100,PBMessage.getDescriptor()); descriptorMap.add(xxx,xxx); 这样Descriptor有了其实还可以做得更好一点通过反射机制Map里面只存放操作码和对应的proto对象类名再通过反射方式创建proto对象在获得其getDescriptor()方法。这样就可以在配置文件中配置操作码和proto对象的关系了。 好接下来我们来接受客户端的请求试一下 //客户端伪代码 client.send(byte_PBMessage); 然后服务器接受请求并解析 //服务器伪代码 byte[] dateserver.accept(); //客户端操作码 int actionCode; Descriptor descriptordescriptorMap.get(actionCode); //解析请求 DynamicMessage reqDynamicMessage.parseFrom(descriptor, date); 在这里我们发现似乎还少了点什么好像 actionCode还不知道怎么办呢好吧我们在客户端发送的请求消息头上再加上个actionCode即把操作码和proto消息合并为一个新的请求发送给客户端请求2位为操作码那么现在客户端应该这么发送消息了 //客户端伪代码 short actionCode100; //两个字节来存放actionCode byte [] actionCodeBytenew byte [2]; // 转换成字节流 actionCodeByte.set(actionCode.toByteArray());//伪代码请勿当真 //带请求头的消息的总长度 int lengthactionCodeByte.lengthbyte_PBMEssage.length; byte [] messageBytenew byte[length]; //把操作码和proto消息合并 messageByteactionCodeBytebyte_PBMEssage; client.send(messageByte); 下来是服务器了 //服务器伪代码 byte[] dataserver.accept(); //把前两位取出来 byte[] actionCodeBytedata.read(0,2); // actionCode有了 int actionCodeactionCodeByte.readShort(); // 取出proto消息 byte[] byte_PBMessagedata.read(2,data.length); .....接下来就和前面的服务器伪代码一样了 DynamicMessage reqDynamicMessage.parseFrom(descriptorMap.get(actionCode, byte_PBMessage); .... 至此动态创建对象完成了,接下来就是按照第一种方式维护的ActionMap通过actionCode取到action来处理DynamicMessage 解析好的请求了 当然actionCode也可以换成actionName类似的。到这里似乎差不多了当时始终不完美因为我们还没有把DynamicMessage 转换成PBMessage对象在后续的action里处理DynamicMessage总是不舒服解决办法是通过DynamicMessage对象获得Descriptor对象在获得其所有字段名和值 然后看一下这个地址的这篇文章通过字段反射对象部分http://liufei-fir.iteye.com/blog/1160700通过反射来还原PBMessage以上是经过试验成功的由于时间原因就不把源码贴上来了。有什么问题希望大家指正。 转载于:https://my.oschina.net/u/257088/blog/277461
http://www.pierceye.com/news/476540/

相关文章:

  • 知名网站制作公司排名徐州人才网最新招聘2023
  • 网站建设与网页设计难学吗做彩票的网站
  • 请问怎么做网站郑州小程序开发制作
  • 城乡建设网站职业查询系统小公司根本办不了icp许可证
  • 网站架构搭建搭建网站是什么专业
  • 互助网站建设电脑做网站端口映射
  • 电力行业做的好的招投标网站wordpress 自定义注册表单
  • 网站开发采集工具网站设计计划书的要求
  • 技术支持:佛山网站建设珠海网站制作服务
  • 公司网站建设方案ppt网站下载织梦模板
  • 免费创建虚拟网站漳州鼎信
  • 武义县网站建设公司上海seo外包
  • 免费html网站模板下载怎么做网站外链接
  • 南昌网站建设公司收费桂林做网站的公司有哪些
  • 南京网站建设方案智能管理系统
  • 黄埔网站建设价格资源网站推广
  • 桦南县建设局网站动漫制作技术和动漫设计
  • 在农村开个网站要多少钱网站客户运营
  • 免费做文字图网站企业所得税计算方式
  • 做网站要有策划么设计师专用网站
  • 站长之家是什么哈尔滨模板建站服务商
  • 自己做网站需要备案么关键词seo资源
  • 用tornado做网站网站建设素材库
  • dedecms织梦古典艺术书画书法公司企业网站源码模板wordpress 优酷插件
  • 深圳购物网站建设301跳转wordpress
  • 如何做自己的加盟网站开发高端客户
  • 沈阳网站建设哪里好wordpress模块管理系统
  • 跨境外贸平台有哪些天津百度快速排名优化
  • 网站建设需要了解哪些方面企业的网站建设与设计论文
  • 网站建设市场分析内蒙古企业网站建设