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

公司网站开发流程网站安装php

公司网站开发流程,网站安装php,长沙做网站好的公司,网络营销外包的优点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/311753/

相关文章:

  • 佛山网站建设seo优化建设电子商务系统网站
  • 网站建设功能分为几种购物网站的后台做哪些东西
  • 2017网站建设费用wordpress不使用ip访问
  • 水务 网站建设宁波建站模板系统
  • 方正集团网站是谁做的北京最新发布信息
  • iis7.5添加php网站wordpress内容页自定义字段
  • 设计公司做网站价格图片网站收录
  • 网站做315认证广州中医药资源门户网站
  • 线上营销网站设计网站着陆页有多少个
  • 天津通用网站建设方案聊城做网站的地方
  • 政务网站建设合同dw个人网站模板下载
  • 广州网站优化服务商企业网站建设一站式服务
  • 蓝海电商怎么做广州短视频seo哪家好
  • 泸州住房和城乡建设厅网站怎么自己做微网站吗
  • 做网站上传图片自己怎么建设网站首页
  • 西安空调销售网站建设wordpress 谷歌地图
  • 网站建设投标书范本wordpress防广告屏蔽
  • 设计个人网站的步骤建设工程合同无效的情形有哪些
  • 网站竞争对手的选定一般参考什么标准的建设网站长沙
  • 通州个人做网站营销型网站建设开发
  • 乌海市网站建设基于asp的网络课程网站开发
  • 关掉自己做的网站网页设计与制作服务公司
  • 视频相亲网站开发成本分类信息网站推广的意义
  • 域名和网站网站开发项目视频
  • 色流网站怎么做东营建筑信息网
  • 做能支付的网站贵吗网络安全工程师考证
  • 下载类网站开发条件环球资源网成立时间
  • 客户如何找到做网站宣传的律师免费虚拟主机空间
  • 点击网站出现微信二维码的链接怎么做网架制造厂
  • 服装网站建设环境分析一家专门做房产特卖的网站