说明
下面将介绍schat服务框架所使用的序列化协议,所使用的协议从功能来说分为两类:
- 服务器进程之间通信协议
- 服务器与客户端通信协议
服务进程通信协议
服务器内部进程一般会部署在一个idc之中,内网通信,较为稳定和高效。我们使用protobuf作为协议描述和序列化工具,性能和兼容性都较好,官方本身也对go提供了良好的支持。具体的protobuf安装和go支持已经在上一篇说明,这里介绍具体的通信协议。
-
描述
下面摘自schat/proto/ss/ss.proto文档,描述了大概的协议轮廓:syntax="proto3"; package ss; import "basic.proto"; import "chat.proto"; import "disp.proto"; import "user_info.proto"; /* Server-Server Proto */ //proto type enum SS_PROTO_TYPE { HEART_BEAT_REQ = 0; HEART_BEAT_RSP = 1; PING_REQ = 2; PING_RSP = 3; LOGIN_REQ = 4; LOGIN_RSP = 5; LOGOUT_REQ = 6; LOGOUT_RSP = 7; REG_REQ = 8; REG_RSP = 9; CREATE_GROUP_REQ = 12; CREATE_GROUP_RSP = 13; USE_DISP_PROTO = 14; // serv <--> disp <--> serv APPLY_GROUP_REQ = 16; ... }
上面包含了内部通信的宏定义。具体的通信结构都包含在SSMSG里,如下所示:
//main msg message SSMsg { SS_PROTO_TYPE proto_type = 1; oneof msg_body { MsgHeartBeatReq heart_beat_req = 20; MsgPingReq ping_req = 22; MsgPingRsp ping_rsp = 23; MsgLoginReq login_req = 24; MsgLoginRsp login_rsp = 25; MsgLogoutReq logout_req = 26; MsgLogoutRsp logout_rsp = 27; MsgRegReq reg_req = 28; MsgRegRsp reg_rsp = 29; MsgCreateGrpReq create_group_req = 30; MsgCreateGrpRsp create_group_rsp = 31; MsgDisp msg_disp = 32; MsgApplyGroupReq apply_group_req = 34; MsgApplyGroupRsp apply_group_rsp = 35; MsgApplyGroupNotify apply_group_notify = 36; MsgApplyGroupAudit apply_group_audit = 37; MsgFetchApplyGrpReq fetch_apply_req = 38; MsgFetchApplyGrpRsp fetch_apply_rsp = 39; MsgCommonNotify common_notify = 40; ... } }
如上所述,定义了全部的内部通信协议结构体,使用命令
protoc --go_out=. ss.proto
即可生成相应的go描述文件 -
序列化
源码schat/proto/ss/api.go中提供了对协议的序列化和反序列化接口:const ( MAX_SS_MSG_SIZE=(200*1024) //200k ) func Pack(i interface{}) ([]byte, error) { switch i.(type) { case proto.Message: m , _ := i.(proto.Message); return proto.Marshal(m); def