IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> [自己做个游戏服务器]搞清楚游戏通信协议之protobuf的方方面面,评论继续送书 -> 正文阅读

[Java知识库][自己做个游戏服务器]搞清楚游戏通信协议之protobuf的方方面面,评论继续送书

目录

1、protobuf 环境搭建

2、protobuf 语法

2.1 注释规则

2.2 数据类型

2.3 默认值规则

2.4 protobuf 选项

2.5 protoc 生成java文件

3、idea 生成插件

3.1 GenProtobuf

3.2 protobuf

4、序列化和 反序列化

4.1 常规序列化和反序列化

4.2 通用的反序列化

5、protostuff

6、总结


最近准备启动写个gameserver的计划,所以开始准备,网络协议方面准备使用protobuf ,这也是现在最流行的,最多使用的,所以今天就写下protobuf,虽然在项目中也一直在使用,但是也只是惯性使然,今天就全面的复习下,避免在使用的时候卡壳。开始吧。

注:因为使用java的缘故,所以我就我的经验写下protobuf在java中的使用,因为其他的语言不是很熟,同时经验不多,但是大同小异。

1、protobuf 环境搭建

protobuf是由Google开发的一套对数据结构进行序列化的方法,可用做通信协议,数据存储格式,等等。其特点是不限语言、不限平台、扩展性强,就像XML一样。与XML相比,protobuf有以下特点:

1.1 protobuf 的版本

最新版本地址:Releases · protocolbuffers/protobuf · GitHub

image-20210930151928879.png

Maven 依赖配置,直接放进去,不用想太多

        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.18.0</version>
        </dependency>

1.2 proto编译器

将主页一直往下拉,可以看到protoc的各种系统版本,根据自己的操作系统选择,我的是64位的win10 ,所以选择了win64,下载后解压就好,等会使用

image-20210930152050299.png

2、protobuf 语法

proto3 的语法文档 :https://developers.google.com/protocol-buffers/docs/proto3

syntax = "proto3";
?
message SearchRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
}

2.1 注释规则

为你的.proto 添加注释,使用 C/C++风格的 // 或者 /* ... */ 语法.

/* SearchRequest represents a search query, with pagination options to
 * indicate which results to include in the response. */
?
message SearchRequest {
  string query = 1;
  int32 page_number = 2;  // Which page number do we want?
  int32 result_per_page = 3;  // Number of results to return per page.
}

2.2 数据类型

基本上也都是常规的数据类型

数值: int32,int64,float ,double ,s开头(可变的,也就是编码的时候更紧凑),u开头(也就是无符号的,只能是正值),fix(固定长度的,一般不怎么用)

布尔值:bool

字符串:string

枚举 : enum

列表:repeated

二进制:bytes

基本上常用的也就是这些简单的类型,没什么特殊的。

2.3 默认值规则

定义了数据类型的,在不传的时候的默认值的规则是什么,下面以Java 为主

  • string:默认值是”“

  • bool : 默认值 是false

  • 数值类型:默认值是0,0.f或者0.D.

  • 枚举:默认值是第一个枚举值,也就是0

  • message 复合类型:在Java中时null.

    message SearchResponse {
      repeated Result results = 1;
    }
    ?
    message Result {
      string url = 1;
      string title = 2;
      repeated string snippets = 3;
    }

2.4 protobuf 选项

protobuf 提供了一些选项设置生成的proto文件

option java_package = "com.example.foo";
option java_outer_classname = "Ponycopter";
option java_multiple_files = true;
option optimize_for = CODE_SIZE;
?

option java_package = "com.example.foo";?生成的java文件所在的包名

option java_outer_classname = "Ponycopter";生成的类的名字

option java_multiple_files = true;如果是false 则整个proto文件生成在一个java文件中,true 则一个message 生成一个java文件,注:不写的时候默认是false

option optimize_for = CODE_SIZE;可以设置为?SPEED,?CODE_SIZE,?LITE_RUNTIM

SPEED : 代码的序列和转换等速度优先

CODE_SIZE:优化生成的代码大小

LITE_RUNTIME:生成的代码需要更少的运行时,一般不选用此选项。

2.5 protoc 生成java文件

拷贝你下载的protoc.exe 到你的proto 文件的所在地址,在文件夹shfit + 右键 ,选择打开cmd 窗口 运行下面的

protoc --java_out=./ XX.proto

--java_out?就是生成的输出地址

xx.proto?就是你要编译的proto 文件

不信你试试

3、idea 生成插件

java中开发最常用的就是IDEA 了,因为idea 的强大插件体系是真的好用,protobuf 的开发在idea中也是很方便,这里推荐两个proto的插件,助你在开发的时候如虎添翼。

3.1 GenProtobuf

生成proto 每次都输入命令有点烦的,所以有人写了插件genprotobuf ,在idea中点点就可以了,

安装:很简单,File -> Settings->Plugins,然后点击install 就可以了,等安装完成后就可以了

image-20210930160147779.png

配置:Tools -> Config GenProtobuf

image-20210930160632320.png

生成java文件:选择需要生成的proto文件,然后选择 quick gen protobuf rules ,可以按上一步配置的规则生成java文件

image-20210930160904940.png

3.2 protobuf

protobuf 插件是支持proto文件的语法,对关键字进行高亮

image-20210930160957800.png

4、序列化和 反序列化

4.1 常规序列化和反序列化

常规的使用

        SimpleMessage.Builder builder = SimpleMessage.newBuilder();
        builder.setName("香菜");
        builder.setId(1);
        builder.setIsSimple(true);
        byte[] result=builder.build().toByteArray();//序列化
?
        SimpleMessage msg;
        try {
            msg = SimpleMessage.parseFrom(result);
            System.out.println(msg);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }

4.2 通用的反序列化

使用parser 进行反序列化,保存每个消息的parser,可以在启动的时候对消息进行扫描,将消息id 对应的协议进行保存

import com.google.protobuf.Parser;
import com.xin.msg.login.SimpleMessage;
?
import java.util.HashMap;
import java.util.Map;
?
public class MsgMgr {
    public static Map<Integer, Parser> msgMap = new HashMap<>();
    static {
        //  msgId - parser
        msgMap.put(1, SimpleMessage.parser());
    }
}
?

在进行解析的时候根据消息Id获取对应的parser 转换为 对应的消息,统一转换

        Parser parser = MsgMgr.msgMap.get(headId);
        int canReadBytes = decode.readableBytes();
        byte[] data = new byte[canReadBytes];
        decode.readBytes(data);
        Object o = parser.parseFrom(data);

5、protostuff

使用protobuf 需要写proto 文件,这个文件是为了和客户端同步,其实有点烦,再把它编译成目标语言,这样使用起来就很麻烦。但是现在有了protostuff之后,就不需要依赖.proto文件了,他可以直接对POJO进行序列化和反序列化,使用起来非常简单。

github 地址 :GitHub - protostuff/protostuff: Java serialization library, proto compiler, code generatorhttps://github.com/protostuff/protostuff

maven 依赖,加到你的pom.xml就可以了

<dependency>
  <groupId>io.protostuff</groupId>
  <artifactId>protostuff-core</artifactId>
  <version>1.7.4</version>
</dependency>
<dependency>
  <groupId>io.protostuff</groupId>
  <artifactId>protostuff-runtime</artifactId>
  <version>1.7.4</version>
</dependency>

实例;

public final class Foo
{
    String name;
    int id;
    
    public Foo(String name, int id)
    {
        this.name = name;
        this.id = id;
    }
}
?
static void roundTrip()
{
    Foo foo = new Foo("foo", 1);
?
    // this is lazily created and cached by RuntimeSchema
    // so its safe to call RuntimeSchema.getSchema(Foo.class) over and over
    // The getSchema method is also thread-safe
    Schema<Foo> schema = RuntimeSchema.getSchema(Foo.class);
?
    // Re-use (manage) this buffer to avoid allocating on every serialization
    LinkedBuffer buffer = LinkedBuffer.allocate(512);
?
    // ser
    final byte[] protostuff;
    try
    {
        protostuff = ProtostuffIOUtil.toByteArray(foo, schema, buffer);
    }
    finally
    {
        buffer.clear();
    }
?
    // deser
    Foo fooParsed = schema.newMessage();
    ProtostuffIOUtil.mergeFrom(protostuff, fooParsed, schema);
}
?

protostuff 就不具体介绍了,官方地址也贴上了,同时我也没在项目中使用,原因就是proto 文件还要发给客户短使用,proto是和客户端进行协议沟通的桥梁,要不然就要客户端自己写proto文件了,容易造成协议不一致。

6、总结

protobuf 只是一个通信协议,虽然有很多细节,但是并不需要太过于深入,等你遇到问题的时候再查文档不晚,记住常用的数据类型,工作中不影响搬砖就可以了,加油,下一步用起来。

送书,送书,送书

随着网络技术的迅速发展,如何有效地提取并利用信息,以及如何有效地防止信息被爬取,已成为一个巨大的挑战。本书从零基础开始讲解,系统全面,案例丰富,注重实战,既适合Python程序员和爬虫爱好者阅读学习,也可以作为广大职业院校相关专业的教材或参考用书。础操作、图形处理基本操作、简单图形的绘制和对象的管理等内容

京东自营购买链接:

《Python爬虫与反爬虫开发从入门到精通》(刘延林)【摘要 书评 试读】- 京东图书

当当自营购买链接:

《Python爬虫与反爬虫开发从入门到精通》(刘延林)【简介_书评_在线阅读】 - 当当图书

大家点赞关注,三天后在留言的同学中抽取送一本书

注:如果中奖了没关注则放弃

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-10-06 12:04:30  更:2021-10-06 12:05:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:11:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码