欢迎阅读我的开源项目《迷你微信》服务器《迷你微信》客户端

protocolbuffer(以下简称Protobuf)是google 的一种数据交换的格式,它独立于语言,独立于平台。google 提供了三种语言的实现:java、c++ 和 python,每一种实现都包含了相应语言的编译器以及库文件。由于它是一种二进制的格式,比使用 xml 进行数据交换快许多。可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于诸如网络传输、配置文件、数据存储等诸多领域。——维基百科

使用原因

在不同语言的前后端交互时,由于不能直接调用,所以必须有一套相同的读写协议来规定数据的格式,也就是说,在服务器与客户端交互时,将要传输的内容按照规定模式转化为一种中间语言(byte数组),然后在另一端根据同样的格式转换回自己语言的对象,在这个过程中,可能会出现一些问题,如:

  • 协议的内容需要繁琐的交流协商,以保证双方一致。
  • 很可能出现在失误的情况下,导致数据对错位问题。
  • 在协议变更的时候,双方都要进行修改,这是一种潜藏的隐患。
  • 可能由于不同语言之间,变量类型的不同导致双方结果不同。

而Protobuf的出现,解决了这样一种隐患。首先Protobuf是用一种独立的Protob语言写的,简单易懂,并且从这一层直接去除掉语法错误问题;接着,Protobuff可以通过需要编译成不同的语言,从这一层解决了双方不一致和变更时衍生的问题。

定义Protobuf

在这里咱们简单的介绍一下Protobuf的几个常用语法:

package protocol;
import "Member.proto"; option java_package = "protocol.Data"; message UserItem{
enum Sex{
MALE = 0;
FEMALE = 1;
}
required string userName = 1;
required Sex sex = 2;
optional int32 father = 3;
repeated PersonalInfo personalInfo = 4;
}

咱们来解释一下这里面的代码分别是什么意思:

import "Member.proto";表示导入另一个Protobuf,这样就可以使用里面定义的message 对象PersonalInfo 了。

option java_package = "protocol.Data";表示将这个写好的Protobuf文件在编译时编译如protocol/Data文件夹下。

message UserItem表示对象的名称,比如编译成Java文件后,就是叫做UserItem.java的文件。

enum Sex是一个枚举的使用,下面就用到了这个Sex

required string userName = 1;表示UserItem这个对象中有一个叫userName的参数,参数类型是Stringrequested表示在使用时,这个参数必须被填入,否则将报错!

optionalrequested使用方式类似,表示在使用中这个参数可填可不填。

repeated PersonalInfo personalInfo = 4中的repeated则表示这个参数可能有多个(可以没有),PersonalInfo类型来自import "Member.proto";

注意:.proto文件不能与定义的对象名(在这里是UserItem)相同,否则会编译失败!帖主就在此栽过跟头。o(>﹏<)o

使用

这里只介绍Java中对于Protobuf的使用(可参考《迷你微信》服务器),想了解C#对Protobuf的使用,请参考《迷你微信》客户端

开始

想要在Java中使用Protobuf,首先要定义好Protobuf,然后用控制台指令进行编译,控制台在.proto文件的地址下,输入protoc --java_out=./ ./(我的proto文件名).proto

运行成功后,会在制定目录下出现(我的proto文件名).java文件,将其复制到你的Java项目中就可以使用了。

创建

当你要将你的数据转化为Protobuf对象时,需要这样创建:

import UserItemMsg;
.......... // 创建
UserItemMsg.UserItem.Builder builder = UserItemMsg.UserItem.newBuilder();
// 设置数值
builder.setUserName = "枫露霜阳";
builder.setSex(UserItemMsg.UserItem.Sex.MALE);
builder.addPhone = "18252060997";
builder.addPhone = "110";
// 要build起来
UserItemMsg uim = builder.build();
// 若是要转成byte数组
byte[] byteArray = uim.toByteArray();

上述代码将Protobuf在java中的类创建、设值、build、转为byte数组,最后用于网络传输。

反解

上面将Protobuf的Java类转化为byte数组,然后通过网络传输,到了接收端,如何将其解回Java对象呢?

import UserItemMsg;
............... // 得到传过来的byte数组
byte[] byteArray = fromClientByteArray;
UserItemMsg.UserItem userItem = UserItemMsg.UserItem.parseFrom(byteArray);
// 获取数值
String userName = userItem.getUserName();

后话

至此,我们就把Protobuf的简单使用描述了一遍,若想看看帖主项目的详细使用请戳下面传送门。

欢迎阅读我的开源项目《迷你微信》服务器《迷你微信》客户端

【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:6.技术简介之Protobuf的更多相关文章

  1. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:0.概述

    欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 序言 帖主和队友仿制了一个简单版的微信,其中,队友是用Unity3D做前段,帖主用Java的Mina.Hiberna ...

  2. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:7.项目介绍之架构(1)

    欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 前言 <迷你微信>服务器端是使用Java语言,Mina框架编写的,一个良好的架构关系到后期迭代的方便程度 ...

  3. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:9.观察者模式

    欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 前言 在一个程序的迭代过程中,复杂度渐渐上升,可能会出现一些跨模块的调用的需求,若是直接得到引用来进行使用,会导致模 ...

  4. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:8.自定义传输协议

    欢迎阅读我的开源项目<迷你微信>服务器)与<迷你微信>客户端 前言 在上一篇中,我们讲到了<迷你微信>服务器)的主体架构,还讲到了如何在现有功能上进行拓展,但是拓展 ...

  5. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:5.技术简介之Hibernate

    目录 序言 配置 hibernate.cfg.xml配置文件 加载hibernate.cfg.html配置文件并获取Session 对象的注解配置 增删改查 具体的增删改查代码 数据库操作的封装 连接 ...

  6. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统 :1.技术简介之Mina连接

    欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 Apache MINA(Multipurpose Infrastructure for Network Applic ...

  7. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:4.技术简介之Spring

    欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 Spring是一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One ...

  8. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:3.技术简介之MinaFilter——LoggingFilter (转)

    欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 LoggingFilter 接下来,使我们对Filter介绍的最后一个——LoggingFilter. 与Proto ...

  9. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:10.项目介绍之架构(2)

    欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 前言 前面我们讲到<迷你微信>服务器端的主架构,现在我们来描述一下它的模块详细信息. 网络模块 从上图我 ...

随机推荐

  1. 6 大主流 Web 框架优缺点对比:15篇前端热文回看

    摘自:http://blog.csdn.net/VhWfR2u02Q/article/details/78993079 注:以下文章,点击标题即可阅读 <6 大主流 Web 框架优缺点对比> ...

  2. SQL查询 若为空显示默认值

    COALESCE(a.end_,now()) SELECT COALESCE(NULL,NULL,3,4,5) FROM

  3. C# -- 继承规则

    例子1--C#继承的常见问题: using System; using System.Collections.Generic; using System.Linq; using System.Text ...

  4. FormsAuthentication.RedirectFromLoginPage 登录

    首先讲的这个东西是针对后台数据访问的比如我的后台是admin文件夹.那么我除非登陆成功才可以访问里面的东西.那么除了Session对象判断.和Cookies来判断还能用到FormsAuthentica ...

  5. 使用Django创建一个后端是SQLSERVER的简单系统(一)Django连接SQLServer数据库

    window环境下Django连接SQLSERVER, 1.创建项目: 2.创建application: 3.使用pycharm打开项目,如下图: 4.配置虚拟环境: 安装Django\pyodbc\ ...

  6. MATLAB进行无约束优化

    首先先给出三个例子引入fminbnd和fminuc函数求解无约束优化,对这些函数有个初步的了解 求f=2exp(-x)sin(x)在(0,8)上的最大.最小值. 例2 边长3m的正方形铁板,四角减去相 ...

  7. Python-OpenCV中图像颜色空间转换

    目录 cv2.cvtColor() 1. RGB to GRAY 2. RGB to CIE XYZ 3. RGB to YCrCb JPEG 4. RGB to HSV 5. RGB to HLS ...

  8. 对zabbix监控磁盘性能的补充

    原因 在上一篇文章中,我写了完整的磁盘监控步骤,希望对大家有所帮助.但是这里还需要作出一点补充. 根据上一篇文章的内容,我是使用iostat命令不停的收集磁盘的信息,然后写入到/tmp/iostat_ ...

  9. springboot jpa mongodb 多条件分页查询

    public Page<Recorded> getRecordeds(Integer page, Integer size, Recorded recorded) { if (page&l ...

  10. http系列--从输入 URL 到页面加载完成的过程

    一.前言 这道题的覆盖面可以非常广,很适合作为一道承载知识体系的题目.每一个前端人员,如果要往更高阶发展,必然会将自己的知识体系梳理一遍,没有牢固的知识体系,无法往更高处走! 二.主干流程 在将浏览器 ...