Protocol Buffer使用轉換工具將proto文件轉換成Java文件流程及使用

Client與Server的網絡通信協議傳輸使用google protobuf,服務器端使用的是Java

一、 Protocol Buffers
protobuf全稱Google Protocol Buffers,是google開發的的一套用于數據存儲,網絡通信時用于協議編解碼的工具庫。它和XML或者JSON差不多,也就是把某種數據結構的信息,以某種格式(XML,JSON)保存起來,protobuf與XML和JSON不同在于,protobuf是基于二進制的。主要用于數據存儲、傳輸協議格式等場合。那既然有了XML等工具,為什么還要開發protobuf呢?主要是因為性能,包括時間開銷和空間開銷:

1.時間開銷:XML格式化(序列化)和XML解析(反序列化)的時間開銷是很大的,在很多時間性能上要求很高的場合,你能做的就是看著XML干瞪眼了。

2.空間開銷:熟悉XML語法的同學應該知道,XML格式為了有較好的可讀性,引入了一些冗余的文本信息。所以空間開銷也不是太好(應該說是很差,通常需要實際內容好幾倍的空間)。

二、服務器端生成的proto文件轉換成Java文件

示例:proto文件

syntax = "proto3";

option java_package = "com.showly.app.chat.proto";//生成Java文件后的存放路徑
option java_outer_classname = "ChatServerProto";


// 聊天內容類型
enum ContentType {
    NORMAL = 0;         // 普通文本聊天
    ANONYMOUS = 1;         // 匿名文本聊天(輸入框旁邊有個勾選)
}


// 性別
enum GenderType {
    SECRET = 0;             // 保密
    MALE = 1;                //
    FEMALE = 2;                //

}


// 用戶信息
message UserInfo {
    int32 uid = 1;
    string headPic = 2;
    GenderType gender = 3;
    bool vip = 4; //Vip
    int32 level = 5; //等級
    string nickName = 6; //昵稱
}



// 響應消息的一個頭. 每個消息都會帶上.
message ResponseHeader {
    int32  status = 1;            // 狀態 非0 為失敗
    string  msg = 2;             // 狀態描述
}


// 聊天使用的消息體對象
message ChatInfo {
    UserInfo info = 1;             // 用戶信息
    string location = 2;             // 用戶的位置. 
    ContentType type = 3;             // 消息類型
    bytes content = 4;             // 消息內容
    int64 dt = 5;                 // 時間戳
}


// cmdId = 1000(客戶端傳輸到服務器端的請求id)
message LoginRequest {
    int32 uid = 1;             //uid
    string token = 2;        // token
}

// cmdId = 1000000(客戶端獲取服務器端響應id)
message LoginResponse {
    ResponseHeader header = 1;
    repeated ChatInfo chats = 2;            // 10條歷史記錄
    bool roomReconn = 3;                 // 房間重連
}


// cmdId = 1001 切換城市 世界為 "WORLD"
message ChangeCityRequest {
    string  city = 1;                  // city code
}


// cmdId = 1000001
message ChangeCityResponse {
    ResponseHeader header = 1;
    repeated ChatInfo chats = 2;// 10條歷史記錄
}


enum LocationType {
    WORLD = 0;//世界信息
    REDBAGROOM = 1; //紅包活動房間
}


// cmdId = 1002
message SendChatMsgRequest {
    string location = 1;        //位置
    ContentType type = 2;         // 消息類型
    bytes content = 3;             // 消息內容. 以后可能圖片什么. 我這里不寫死. 客戶端給我字節數組.
    LocationType locationType = 4 ;// 消息位置
}

// cmdId = 1000002  推送的聊天信息廣播協議
message ChatInfoBroadcastResponse {
    ResponseHeader header = 1;     
    ChatInfo chat = 2;         // 廣播的內容
    LocationType locationType = 3 ;// 消息位置
} 

// cmdId = 1003 心跳. 不需要發送東西. 告訴服務器還活著
message HeartRequest {

}

// 這里僅服務端使用這個, 客戶端按照下行的id 解析即可.
message DefaultHeaderResponse {
    ResponseHeader header = 1;         //
}

轉換流程:
1、這時需要protoc轉換工具(公眾號回復"protocbuf轉換工具")

2、將proto文件放到工具相應的目錄(如圖)

3、使用如圖命令行進行轉換

轉換后的Java文件為ChatServerProto(生成的文件代碼太長,這里不放出來了)

三、Protocol Buffer使用

以使用Netty網絡編程框架Protocol Buffer傳輸為例:

Netty登錄請求(此協議為客戶端與服務端雙方規定好的協議)
// cmdId = 1000
message LoginRequest {
    int32 uid = 1;             //uid
    string token = 2;        // token
}

項目代碼中使用:

ChatServerProto.LoginRequest loginRequest = ChatServerProto.LoginRequest
                .newBuilder()
                .setUid(Integer.parseInt(I8ShowSharePre.getHomeId(getActivity())))
                .setToken(I8ShowSharePre.getToken(getActivity()))
                .build();

        MessageContent messageContent = new MessageContent(1000, loginRequest.toByteArray());
        //nettyChatClient為netty對象
        nettyChatClient.sendMessage(messageContent);

以下是個人公眾號(longxuanzhigu),之后發布的文章會同步到該公眾號,方便交流學習Android知識及分享個人愛好文章:

posted @ 2019-06-21 09:26 龍旋之谷 閱讀(...) 評論(...) 編輯 收藏