网络游戏中无论采用什么语言开发 ,序列化和反序列化工具 google的 flatbuff 和protobuf 都是首选!java
flatbuf后起之秀和protobuf中有一个共同的特性,那就是在游戏开发中对应的发序列化后的实体和对应的处理函数的对应关系。c++
能够采用传统的if else or switch case,若是 可是在实际的场景中要求快速响应。上述确定是不可以知足实际的开发需求。游戏中区分消息以及消息对应的处理函数都是经过ID来查找。一般设计方案有以下2种:spring
1.用数组来存储,ID做为数组下标,对应处理函数或则对应处理函数的引用做为存储值。编程
2.经过map来存储。ID作key,对应处理函数或则对应处理函数的引用做为存储值。 数组
两种数据结构,。针对java c++ 高级的编程语言(支持多态)处理都不错。不过有一点要注意,java中不可以存储function。因此在对应的2中方案中对应的值应该是处理函数的引用!这点要注意。c++ 则不一样,能够存储引用或则function。 服务器
这里游戏数据包结构:packageLength +ID+message,其中packageLength为ID和message数据的总长度。 网络
游戏中在业务层分发数据的时候,先解析出ID,而后经过上面的2中方式获取对应处理函数或则对应处理函数的引用做为存储值。调用处理函数,将对应的消息派发出去。 session
通常处理函数能够定义为void (session ,message);---这里 本身根据实际的场景来定义吧,seesion一般是一个player ? client 什么的,message 就是对应的那个pb实体消息类型--- 能够在分发的时候将字节数组转化为pb实体,亦能够在业务处理函数层转化。 数据结构
下面具体解析下处理数据和pb实体的关系处理(主要用数组方式,map是同样的处理): 编程语言
首先全局初始化一个静态的数组(c++版本):
typedef function<void(int , int )> DispatcherMessage; static DispatcherMessage *array_message_hand_ref = new DispatcherMessage[1000];
业务处理函数
void testFunctionMap2(int a, int b){ cout << "std::bind call 2 value of a ,b--->" << a << "," << b << endl; }
对应的初始化ID和function或则引用。(这里的初始化 要注意选择合适的位置和时间 一般在程序初始化的时候)
array_message_hand_ref[2] = std::bind(&testFunctionMap2, std::placeholders::_1, std::placeholders::_2);;
当业务层解析到ID 和对应的消息以后如这里是ID==2:
array_message_hand_ref[2](2,3);
这样就完成了数据的派发。
对于java,采用数组的方式应该用两个数组,ID 做为下标。利用java的多态性。
首先获取对应的引用,调用基类的函数,完成数据派发。
以上2中方案只做为参考。欢迎讨论。
后续。。。。
java 实现方案参考:
/** * Created by 石头哥哥 on 2015/2/7. * Content: 测试泛型接口 */ public interface Function<T extends Object, M extends Message> { /** * 处理游戏逻辑接口 * * @param session * @param message */ void DispatcherMessage(T session, M message); }
全部实例处理均继承该类并实现对应的方法
import com.google.protobuf.Message; import javolution.util.FastMap; import javax.annotation.PostConstruct; /** * Created by 石头哥哥 on 2015/2/7. * Content: */ public abstract class BaseController implements Function<Player, Message> { public static FastMap<Integer, Function<Player, Message>> MAP_FUNCTIONS = new FastMap<Integer, Function<Player, Message>>(); /** * 负责初始化 ID 和 处理实体的关系 */ @PostConstruct protected abstract void PreIntiFunction(); }
import com.google.protobuf.Message; import org.springframework.stereotype.Service; /** * Created by 石头哥哥 on 2015/2/7. * Content: */ @Service public class TestController extends BaseController { @Override protected void PreIntiFunction() { MAP_FUNCTIONS.put(1, this); //初始化ID 和 实体处理函数关系 } /** * 处理游戏逻辑接口 * * @param session * @param message */ @Override public void DispatcherMessage(Player session, Message message) { } }
public class Player { }
注意java实现的方案 ,初始化 依赖了spring 整个游戏对象存在spring容器管理,这里只实现了基于map的方案,服务器要求快速相应 仍是推荐选择数组方案 空间换时间,若是是客户端建议用map,内存不足状况下 尤为是手机平台。 技术选型 本身决定!!!