gslang是采用go语言编写的RPC描述语言,最初它被用来描述 gscluster 网络服之间的接口调用契约;而gscluster项目本身是我在tap4fun时开发的一个游戏
服务端框架,所以能够看到 gscluster 里面有很多与游戏相关的概念。但是框架本身是为mico-service
而生的,所以你可以将它应用到任何你觉得合适的地方,不必局限于游戏服务器。
gslang是一个完整的RPC描述语言,它与 thrift 定位相同。没有直接采用thrift的原因是:
gslang前端解析器在github上的位置: 这里
gslang支持的语言特性有:true/false,byte/sbyte,int16/uint16,int32/uint32,int64/uint64,float32/float64,table,struct,enum,contract,annotation
byte/sbyte,int16/uint16,int32/uint32,int64/uint64,float32/float64
table/struct被用来定义用户定义数据类型,table与struct的区别在于table可以被用来定义annotation
示例:
// The cluster message type struct Message { ID byte; //message Type Content []byte; //content data }
进一步示例请参考: 这里
注意:gslang所有数据类型与网络传输格式无关,它只关心接口语言的定义
gslang支持枚举类型,并且可以指定枚举底层数据类型,可选择的数据类型有:byte/sbyte,int16/uint16,int32/uint32
enum Status(uint16){ Closed(0), Disconnected(1), Connecting(2), InConnected(3), OutConnected(4), Online(5), Offline(6), Unreachable(7) }
服务通过contract关键字定义:
contract SampleActor { SayHello(string) -> (bool); }
多参数:gslang方法支持多输入参数、多返回参数
服务接口集成:服务接口支持继承其它服务器接口,这个和java/C#等语言类似
gslang通过类型注释增强了DSL的表达能力,这点与C#/java类似。这个应该是gslang的杀手级特性,它可以被用来指导后端代码生成器生成个性化代码,而不用修改gslang前端编译器部分。在tap4fun的一个内部版本里,通过自定义annotation来决定是否对某个服务器方法生成profile代码。
如前所述,gslang并不关心底层的序列化方式,也就更不关心底层的网络传输方式。这部分协议由gslang的后端代码生成器决定,一个已知的代码生成后端是 gs2go —golang代码生成后端,并且生成代码遵循的协议由 gscluster 定义。
需要指出的是: gscluster 的RPC调用底层数据包本身也是由gslang来描述的,具体情况可以参看 这个 文件。
通过上面几步,就构建了一个基本的gsdocker/rpc测试环境。你可以观察生成的*.gs.go文件来了解代码生成的细节;
直接将字段数据按定义顺序递归序列化写入二进制流,没有tag/元数据信息;它的序列化/反序列化完全依赖于gslang脚本;
客户端/mico-service节点之间的rpc调用都被封装成一个一个RPC协议包传输,它的格式定义由gslang描述为下面形式:
// The gscluster rpc package code types enum Code { WhoAmI(0), Accept(1), Reject(2), DHExchange(3), Call(4), Return(5), CER(6), ErrReturn(7) } // The gscluster prc package type define struct Message { Code Code; //message Type Content []byte; //content data } struct DHExchange { ID string; Content string; } struct CER { Add bool; Type string; // service type name Name string; // service name ID uint32; // srevice id } struct Param{ Content []byte; } struct Return { ID uint16; Service uint32; Params []Param; } struct ErrReturn { ID uint16; Service uint32; UUID []byte; Code int32; } struct Call { ID uint16; Method uint16; Service uint32; Params []Param; }
再次强调:gscluster的rpc协议封包本身是由gslang来直接定义的
结构体Call/Return分别用来实现RPC调用请求/应答:
Service/Contract协议号与名字的映射关系由底层框架确定:
gscluster是一个golang实现的mico-service框架: