C++高性能服務框架revolver:協議接口描述和翻譯語言

在一個稍微複雜的系統中會涉及到多語言編程,例如:後端C++和JAVA,腳本用LUA,前端可能是C++ AS等等。所以所有模塊之間的協議統一變得非常重要,這樣做的目的是減少中間的調試和差錯。在revolver框架中,實現了一個基於簡單的接口語言來實現多語言之間接口協議的實現。所有的協議接口通過一個簡單的def文件就可以將協議翻譯成對應的語言程序代碼,這樣儘可能的避免中間環節的差錯,也大大提高了編碼效率。而且revolver使用的是標準網絡字節序描述協議報文數據,所以可以在各種系統下使用各種語言進行混合編程。

協議接口例子

以下是一個revolver的sample_msg.def事例接口程序文檔:
#生成的文件名
filetitle = sample_msg
#命名空間
namespace  = BASE
#ip地址類型聲明
datatype(Inet_Addr)


#數組定義
typedef array<int8> : INT8_ARRAY
typedef array<int32> : INT32_ARRAY


#二進制數據
typedef string : BIN_DATA


#結構體定義
datatype(CDesc)
{
int8 n_type = 0
string str_desc = ""
INT32_ARRAY arr_fd 
INT8_ARRAY arr_status
}


#協議消息ID定義
var SAMPLE_MSGID = 0xff000001
#協議體和消息關聯定義
message(CSamplePacket, SAMPLE_MSGID)
{
uint8 msg_type = 0
uint16 seq_id = 0
uint32 user_id = 0
uint64 guid = 0
Inet_Addr server_addr
BIN_DATA bin_data
CDesc msg_desc
}

以上是基本的def定義,如果要將協議翻譯成c++框架能認識的協議,就需要通過revolver中提供的協議翻譯器來進行翻譯,協議翻譯器在revolver項目中protocol_analysis工程編譯得到,會生成一個make.exe。生成make程序後,可在命令行裏輸入make  sample_msg.def c++,就可生成對應的C++接口協議。生成的C++接口文件如下:

namespace BASE {

#define SAMPLE_MSGID	0xff000001

typedef string		BIN_DATA;
typedef vector<int32_t>		INT32_ARRAY;
typedef vector<int8_t>		INT8_ARRAY;

class CDesc
{
public:
	CDesc()
	{
		n_type = 0;
		str_desc = "";
	}
	~CDesc()
	{
	}

public:
	int8_t		n_type;
	string		str_desc;
	INT32_ARRAY		arr_fd;
	INT8_ARRAY		arr_status;


	friend BinStream& operator<<(BinStream& strm, const CDesc& packet)
	{
		strm << packet.n_type;
		strm << packet.str_desc;

		int32_t count_0 = packet.arr_fd.size();
		strm << count_0;
		for (int32_t i = 0; i < count_0; i++)
		{
			strm << packet.arr_fd[i];
		}

		int32_t count_1 = packet.arr_status.size();
		strm << count_1;
		for (int32_t i = 0; i < count_1; i++)
		{
			strm << packet.arr_status[i];
		}
		return strm;
	}

	friend BinStream& operator>>(BinStream& strm, CDesc& packet)
	{
		strm >> packet.n_type;
		strm >> packet.str_desc;

		int32_t count_2 = 0;
		strm >> count_2;
		packet.arr_fd.resize(count_2);
		for (int32_t i = 0; i < count_2; i++)
		{
			strm >> packet.arr_fd[i];
		}

		int32_t count_3 = 0;
		strm >> count_3;
		packet.arr_status.resize(count_3);
		for (int32_t i = 0; i < count_3; i++)
		{
			strm >> packet.arr_status[i];
		}
		return strm;
	}

	void  Print(std::ostream& os) const
	{
		os << "CDesc, {";
		os << "n_type = " << (int16_t)n_type << ",";
		os << "str_desc = " << str_desc << ",";
		os << "arr_fd = ";
		for (uint32_t i = 0; i < arr_fd.size(); i++)
		{
			os << arr_fd[i] << ",";
		}
		os << "arr_status = ";
		for (uint32_t i = 0; i < arr_status.size(); i++)
		{
			os << (int16_t)arr_status[i] << ",";
		}
		os << "}";
	}

	friend ostream& operator<<(ostream& os, const CDesc& packet)
	{
		packet.Print(os);
		return os;
	}
};


class CSamplePacket : public CBasePacket
{
public:
	CSamplePacket()
	{
		msg_type = 0;
		seq_id = 0;
		user_id = 0;
		guid = 0;
	}
	~CSamplePacket()
	{
	}

public:
	uint8_t		msg_type;
	uint16_t		seq_id;
	uint32_t		user_id;
	uint64_t		guid;
	Inet_Addr		server_addr;
	BIN_DATA		bin_data;
	CDesc		msg_desc;

public:
	void	Pack(BinStream& strm) const
	{
		strm << msg_type;
		strm << seq_id;
		strm << user_id;
		strm << guid;
		strm << server_addr;
		strm << bin_data;
		strm << msg_desc;
	}
	void	UnPack(BinStream& strm)
	{
		strm >> msg_type;
		strm >> seq_id;
		strm >> user_id;
		strm >> guid;
		strm >> server_addr;
		strm >> bin_data;
		strm >> msg_desc;
	}

	void  Print(std::ostream& os) const
	{
		os << "CSamplePacket, {";
		os << "msg_type = " << (uint16_t)msg_type << ",";
		os << "seq_id = " << seq_id << ",";
		os << "user_id = " << user_id << ",";
		os << "guid = " << guid << ",";
		os << "server_addr = " << server_addr << ",";
		os << "bin_data's size = " << bin_data.size();
		os << "msg_desc = " << msg_desc << ",";
		os << "}";
	}
};
也可以生成lua 或者AS 等。命令make sample_msg.def  lua 或者make sample_msg.def  as。其他的語言類似,也可以根據項目中使用的語言修改協議翻譯器,讓它支持你所用的語言。


def協議接口介紹

       基礎數據類型:

int8                有符號單字節整型數

uint8              無符號單字節整型數

int16              有符號字節整型數

uint16            無符號雙字節整型數

int32              有符號4字節整型數

uint32            無符號4字節整型數

int64              有符號8字節整型數

uint64            無符號8字節整型數

string             字符串

BIN_DATA    二進制數組

Inet_Addr      IP v4地址,包括端口

關鍵字:

var                  數字定義關鍵字

array              數組關鍵字

datatype        數據結構定義關鍵字,類似結構體

message     協議定義關鍵字

typedef          重定義關鍵字

{                     結構的開始

}                     結構的結束

#                    註釋關鍵字


綜述

revolver提供協議接口編程,就是將自動化引入整個框架,減少因爲協議帶來的調試和差錯,重在提高生產效率。這也是revolver框架的主要特性之一。




發佈了39 篇原創文章 · 獲贊 76 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章