TAF(Total Application Framework) 基础通信协议 Tars语言

接口文件

Tars语言是一种类c++标识符的语言,用于生成具体的服务接口文件

Tars文件是Tars框架中客户端和服务端的通信接口,通过Tars的映射实现远程对象调用

Tars文件的扩展名必须以.tars为扩展名

对于结构定义,可以支持扩展字段,即可以增加字段而不影响原有结构的解析,可以在存储/协议等地方单独使用

大小写敏感

词法规则

采用c++的注释规范。

关键字:

void,struct
bool,byte,short,int,double,float,long,
string,vector,map,
key,routekey,
module,interface,
out,
require,optional,
false,true,
enum,const,

所有标识符不能带有’tars_’符号,且必须以字母开头,同时不能和关键字冲突。

支持的基本类型包括以下:

  • void :只能在函数的返回值表示
  • bool :布尔类型,映射到tars::Bool
  • byte :有符号字符,映射到 tars::Char
  • short :有符号短整型,映射到 tars::Short
  • int :有符号整型,映射到 tars::Int32
  • long :有符号长整型,映射到 tars::Int64
  • float :映射到tars::Float
  • double :映射到tars::Double
  • string :映射到 std::string,java:String
  • unsigned byte :无符号字符,c++映射到 unsigend char 其它版本tars::Short
  • unsigned short:无符号短整形c++映射到 unsigned short其它版本 tars::Int32
  • Unsigned int:无符号整形c++映射到 unsigned int其它版本 tars::Int64

枚举类型的定义如下:

enum TE
{
    E1,
    E2,
    E3
};
  • 枚举类型支持在指定枚举变量的值,例如支持:E1 = 1这种定义方式;

  • 第一个定义的枚举类型值为0,这里E1的值为0;

  • 枚举类型在tars文件定义后,通过tars2cpp生成以后,除了会生成相应的enum定义之外,会生成etos和stoe函数,将枚举值转换成字符串,以及将字符串转换成枚举值,在代码调试时会非常方便。

  • 建议在c++的tars文件中,所有接口都以int返回,且返回值在tars文件中以枚举来定义。

Tars文件中可以定义常量,例如:

const int a = 0;
const string s = “abc”;
  • 由于map,vector没有描述常量的值,因此不支持map,vector的定义;

结构定义如下:

struct Test
{
    0  require  string s;
    1  optional int  i = 23;
};
​
key[Test, s, i];
  • 第一列数字表示该字段的标识(tag),无论结构增减字段,该字段得值都不变,必须和响应的字段对应;

  • Tag的值必须要>=0且<=255;

  • require表示该字段必选;

  • optional表示该字段可选;

  • 对于optional字段,可以有一个缺省值,缺省值在编码时默认不打包;

key说明:表示结构的小于比较符号,缺省时Struct是没有小于操作的,如果定义了key,则生成小于比较符:

  • key[Stuct, member…]:
  • Struct:表示结构的名称
  • Member:表示该结构的成员变量,可以有多个;
  • 生成的小于比较操作符,按照key中成员变量定义的顺序进行优先<比较;
  • 生成小于比较操作符以后,该结构就可以作为map的key;

其他:

  • 在Tars的c++语言中,对于结构而言,提供两个成员函数用于直接打印出结构的内容,可以用于调试和记录日志:

  • ostream& display(ostream& _os, int _level=0):直接打印结构的详细内容,主要用于调试;

  • ostream& displaySimple(ostream& _os, int _level=0):所有成员变量自动按照顺序以|分隔打印出来,用于记录日志;

序列用vector来定义,如下:

vector<int> vi;

字典用map来定义,如下:

map<int, string> m;
  • 对于struct,通常不能作为map的key,因此struct没有大小比较符号;

  • 如果需要struct能够作为map的key,需要用less定义struct中成员的比较顺序;

  • 结构中可以定义数组类型,数组用[]来定义,如下:

byte m[5];
  • 对数组类型,在C++生成代码中会同时生成数组长度mLen

  • 对数组赋值后必须同时对数组长度赋值

  • 在非c++版本中数组类型将翻译为vector<类型>

  • byte m[5] 等价于定义vector:5

结构中可以定义byte指针类型,指针用*来定义,如下:

byte *m;

指针类型使用时需要提前预分配内存块,指针需要内存时通过偏移指向预分配内存块,减少解码过程中的内存申请。

  • 对于指针类型,在c++代码中会同时生成mLen,用来指定指针长度。

  • 对指针赋值后必须对长度mLen赋值

  • 在非c++版本中指针类型将翻译为vector<类型>

  • 含有指针类型的数据读取时BufferReader必须用MapBufferReader,同时需要提前设定指针指向内存的buffer

任何struct,map,vector都可以嵌套;

接口定义如下,例如:

interface Demo
{
    int get(out vector<map<int, string>> v);int set(vector<map<int, string>> v);
};

表示输出参数

接口定义后,通过自动代码生成工具(如:tars2cpp)会生成同步接口和异步接口等代码

所有的struct,interface必须在名字空间中,例如:

module MemCache
{
    struct Key
    {
        0 require string s;
    };struct Value
    {
        0 require string s;
    };
​
    interface MemCacheI
    {
        int get(Key k, out Value v);int set(Key k, Value v);
    };
};
  • 名字空间不能嵌套;
  • 可以引用其他名字空间,例如:Demo1::Key

读官方文档相对舒服

发布了202 篇原创文章 · 获赞 14 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/LU_ZHAO/article/details/105021826