Client與Server的網路通信協議傳輸使用google protobuf,伺服器端使用的是Java 一、 Protocol Buffersprotobuf全稱Google Protocol Buffers,是google開發的的一套用於數據存儲,網路通信時用於協議編解碼的工具庫。它和XML或者 ...
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知識及分享個人愛好文章: