Client與Server的網絡通訊協議傳輸使用google protobuf,服務器端使用的是Javajava
1、 Protocol Buffers protobuf全稱Google Protocol Buffers,是google開發的的一套用於數據存儲,網絡通訊時用於協議編解碼的工具庫。它和XML或者JSON差很少,也就是把某種數據結構的信息,以某種格式(XML,JSON)保存起來,protobuf與XML和JSON不一樣在於,protobuf是基於二進制的。主要用於數據存儲、傳輸協議格式等場合。那既然有了XML等工具,爲何還要開發protobuf呢?主要是由於性能,包括時間開銷和空間開銷:編程
1.時間開銷:XML格式化(序列化)和XML解析(反序列化)的時間開銷是很大的,在不少時間性能上要求很高的場合,你能作的就是看着XML乾瞪眼了。數組
2.空間開銷:熟悉XML語法的同窗應該知道,XML格式爲了有較好的可讀性,引入了一些冗餘的文本信息。因此空間開銷也不是太好(應該說是不好,一般須要實際內容好幾倍的空間)。bash
2、服務器端生成的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; // 頭
}
複製代碼
轉換流程: 一、這時須要protoc轉換工具(公衆號回覆"protocbuf轉換工具")數據結構
二、將proto文件放到工具相應的目錄(如圖) app
三、使用如圖命令行進行轉換 框架
轉換後的Java文件爲ChatServerProto(生成的文件代碼太長,這裏不放出來了)工具
3、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知識及分享我的愛好文章: