Tips for thrift
Introduction
I have designed and developed game servers successfully with thrift (http://thrift.apache.org/). I am writing here some tips to share my experience. I hope that this will help someone who is just trying to solve the same problems that I have met.
Background
Thrift is mainly for scalable cross-language services development ( what it's website has written).Someone may mention Google ProtocolBuff. I have used ProtocolBuff some projects. However, I like thrift more than Google protocolbuff. There are two reasons:
- Thrift support array and map. That is so nice.
- The Codes that thrift framework generated are much more readable just like which I writes them myself.
When developing MMO Server, I use messages to communicate with client which is may implemented by different language e.g., as3. So thrift is very suitable for interchange messages. But there is another circumstance to use thrift.As you know the part of the logic of game server, is modified frequently. Along with project progressing, More property will be added to player object or sub structure. So we will add more fields or rows to db for storing extra data. With version issues being considered, that's much more annoying. I create a blob field to db table that stores a thrift object. With advantages of version supporting, It's easy to add more property to player.
Flash AS3 Wrap
Thrift is originally designed for RPC. How it works for RPC is easy to find if you Google it. I will not write more for this part. But there is less articles to introduce how thrift can be used to communicate message in real time system. Thrift support as3 but just for RPC. So I add some files for supporting message communicating. That another reason why I like thrift that the codes are so readable that it's so easy to extend thrift. Though I am not a professional as3 engineer (I am professional in C++), I implement that easily. I implement two functions to wrap serialization and deserialization.
public class FFUtil {
public static function EncodeMsg(msg:TBase, ba:ByteArray):void
{
var tran:FFMemoryTransport = new FFMemoryTransport(ba);
var proto:TBinaryProtocol = new TBinaryProtocol(tran);
msg.write(proto);
}
public static function DecodeMsg(msg:TBase, ba:ByteArray):Boolean
{
var tran:FFMemoryTransport = new FFMemoryTransport(ba);
var proto:TBinaryProtocol = new TBinaryProtocol(tran);
msg.read(proto);
return true;
}
}
I have uploaded flash_example.zip file which includes my extending as3 lib files and a exampl.as file. Actually it's a chat tutorial application using thrift.
C++ Wrap
There are some dissatisfied aspects in thrift C++ implement codes that they depend boost library. Generally it's not a big problem as most of C++ projects have been using boost. But someone who just want to integrate thrift easily finds it annoying. In some mobile app project with C++, they will not want to depend boost too. Actually I don't find good enough reason to must implement thrift of C++ version with boost. Most of use of boost in thrift are for assert test and smart pointer. Thanks to readable codes, I find it easy to wipe dependency of boost. Actually I still recommend you to use official version. But if you just want try thrift as soon as possible you can try this version of no boost. By the way, this C++ version of no boost supports binary encoding only.
int main(int argc, char **argv)
{
shared::SharedStruct msg, dest;
msg.value = "nihao";
std::string data;
ffthrift_t::EncodeToString(msg, data);
printf("data size=%un", data.size());
ffthrift_t::DecodeFromString(dest, data);
printf("dest value=%sn", dest.value.c_str());
return 0;
}
I have uploaded ffthrif_cpp_example.zip file which includes my extending C++ files and a example file.
For Storing
I use MySQL. There I show the model of game structure as an example. For storing players' data I design a table named player_info for players' base property such as level, gold, exp...
The field of Extra_Data is special and important. It is a blob type for storing thrift. For example, I design a such thrif file:
namespace cpp ff
namespace as3 ff
namespace py ff
struct extra_data_t {
1: list<i32> val1
2: string val2
3: map<i32, string> val3
}
thrift-0.9.0.exe -gen cpp msg_def.thrift
I will store extra_data_t
to field of Extra_Data. There are such features:
- Because of supporting of version, we can add more field to
extra_data_t
but not to modify MySQL table structure. We have hundreds of game server so that we always update some of server first, if anything is ok, we make all servers updated to newest version. Thrift and blob make us agile enough to handle these situations. We don't need to modify db frequently and the part of db operations is stable. - Thrift supports list and map which it's convenient for us and it‘s codes are very readable, we can use
extra_data_t
as base structure ofplayer_t
class.
But we must use thrift properly. If you chose to store thrift object to db blob, you will give up query this field by SQL. So my tips are:
- store those field as base type of db that needs to be queried by SQL. Such as level, exp, gold, socre...
- store those field in thrift object that don't needs to queried by SQL. Though thrift object in db blob can't be queried by SQL, not mean it can be queried no way. Thanks to thrift supporting for lots of languages, thrift objects can be queried by scripts. We developed some web pages with PHP to show data from db.
Summary
- Actually here thrift is a serialization and deserialization framework other than RPC framework.
- RPC mechanism doesn't fit for me. I just use thrift to gen message that supports version.
- With supporting version, thrift can be used in db storing data. We will get more agile by storing thrift object in db blob.
- file download: http://www.codeproject.com/Articles/660671/Tips-for-thrift-Message-and-store
- 一次误报引发的DNS检测方案的思考:DNS隧道检测平民解决方案
- Andriod基础——Adapter类
- ORM查询语言(OQL)简介--高级篇:脱胎换骨
- 用Java实现处理日期的工具类——常用日期处理方法
- ORM查询语言(OQL)简介--实例篇
- 漏洞预警 | 海洋CMS(SEACMS)0day漏洞预警
- 【机器学习】分类算法评价
- Java中图片处理工具类——能满足各种需求
- onclicklistener到底怎么用?
- 如何入侵联网智能灯泡——LIFX智能灯泡
- Java实现的一个编号生成器工具类——5种方法
- 【机器学习】有趣的机器学习:最简明入门指南
- 不使用反射,“一行代码”实现Web、WinForm窗体表单数据的填充、收集、清除,和到数据库的CRUD
- 海量数据处理利器之布隆过滤器
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 链表中穿针引线
- Android 帧动画的实例详解
- Android HandlerThread使用方法详解
- LeetCode 167,两数之和2
- 详解android 通过uri获取bitmap图片并压缩
- android线程消息机制之Handler详解
- 分布式一致性协议 - ZAB
- 删除链表的倒数第N个节点
- Open3d学习计划—高级篇 2(彩色点云配准)
- Android7.0上某些PopuWindow出现显示位置不正确问题的解决方法
- 有效的括号
- Android PopupWindow实现左侧弹窗效果
- LeetCode. 209. 长度最小的子数组
- 一篇文章就能了解Rxjava
- 二叉树遍历非递归程序 -- 使用栈模拟系统栈