`
ybak
  • 浏览: 35423 次
  • 性别: Icon_minigender_1
  • 来自: XX
社区版块
存档分类
最新评论

基于netty+ protobuf +spring + hibernate + jgroups开发的游戏服务端

阅读更多

   半年前跟朋友开始创业做手机游戏.我负责一个人开发服务端,这是一个卡牌类多人在线回合制对战网游.开始时第一考虑的是能快速出实现需求.其次是功能的可扩展性(应对频繁变更的需求),再次才是服务器性能.

   目前游戏开发的主流语言仍是C++,但因为自己最熟悉的是java,转C++的成本太高,且国内页游服务器,已经开始大规模应用java作为后端服务器.最终还是确定使用java来开发.

   这里,有两条路可选,1是使用现有的服务器作扩展,2是自己开发服务器.
  
   市面上的成熟的java 游戏服务器寥寥无几,选择并不像web框架那样丰富,可选的收费服务器以smartfox为代表.还有一些开源的但充其量只能作为demo的框架(比如menacher).当时网易的pomelo也还没有出现.

   虽然smartfox宣传有很多成功案例.但看了文档后.发现smartfox最成功的案例是棋牌类游戏和社交类游戏.这和我们要开发的卡牌类RPG手游的游戏交互方面还是有很大的差异.而且smartfox对于游戏的逻辑封装过多.比如基本的概念就是进入游戏房间等.这种封装并不适合于我们要开发的游戏类型.所以购买smartfox没有太多的性价比.果断放弃之.

   接下来就是自己开发游戏服务器的socket server了.
   

    在实现socket server时,先参考了两个开源的游戏服务器实现.一个是永恒之塔的开源私服实现aionxemu,另一个是简单的socket server实现menacher.

  我在看了许多aionxemu的代码实现后.发现这些代码编写开发者一定都是多年的编程老手.代码不光实现了数量庞大的游戏服务接口,还在可扩展性(OO方面)和性能优化上做了很多考究的设计.aionxemu游戏服务器是分为gameserver loginserver和chatserver在gameserver中,接口协议的解析和序列化直接使用的是java nio来操作字节流.直接使用java nio比较繁琐,而操作字节流解析和封装协议也存在同样的问题.虽然能提高性能,但在开发成本和可维护性上有一定弊端,不适合目前我们对进度要求十分紧迫的情况.值得一提的是:aionxemu虽然只是一个私服,但其中具有完整的mmorpg的逻辑实现. 对于我们游戏中的逻辑开发具有相当高的借鉴意义.

   menacher中使用了netty作为NIO操作类库,在其代码中展示了netty的简洁性.比较有意思的是menacher使用了jetlang作为游戏业务事件驱动的reactor处理框架,可以方便的提供逻辑的扩展并提供性能调整配置.但遗憾的是menacher并没有在服务器的横向扩展上做太多的考虑..


   在参考了以上两个实现,再结合项目的实现情况(服务器提供的服务接口可能多达100多个,而且这些接口后续出现变更),在协议处理上我选择了protoc buffer.   Protbuf的跨平台使使用C++的客户端可以方便的序列化协议对象.使用客户端和服务器双方更关注于游戏协议,而非字节流的处理细节.有利于客户端和服务端快速交流. 最后在socket server上采用了netty+protbuf两个框架来实现.netty负责socket处理,protbuf负责处理游戏协议解析.
   协议的基本结构如图:

   

   protobuf的客户端消息协议基本如下所示.

    

message PBClientPacket {
	required PBClientRequestType clientRequestType = 1; //请求类型
	optional bytes requestData = 2; //请求数据
}

enum PBClientRequestType {

	DUMMY_REQUEST = 0; // PBDummyRequest
	UPDATE_REQUEST = 1; // PBUpdateRequest
	REGIST_REQUEST = 2; // PBRegistRequest 
	LOGIN_REQUEST = 3; // PBLoginRequest 
......
}

....

message PBDummyRequest {
	optional string payload = 1;
}

message PBUpdateRequest {
	required string clientVersion = 1; 
......
}
......

      protobuf的服务端消息协议基本如下所示.

 

message PBServerPacket {
	required PBPayloadType payloadType = 1; //服务端报文类型
	optional PBResponseCode code = 2; //
	optional string desc = 3; //
	optional bytes payloadData = 4; //此字段中包含服务端返回的响应内容
}

enum PBPayloadType {
	DUMMY_RESPONSE = 0; 
	UPDATE_RESPONSE = 2; //PBUpdateResponse
        ......
}

enum PBResponseCode {
	OK = 0;
	ERROR_UNKOWN = 1;
	SERVER_ERROR = 2;
......
}

message PBUpdateResponse {
	optional string resourceURL = 1;
	optional bytes resoruces = 2;
        ......
}

 客户端和服务器端的消息结构类似.,第一个字段表示消息类型,程序在知道消息类型后.就可以根据协议来化序列化后面的报文字段.在具体的请求对象外再封装一层统计的交互对象,会有利于netty与protobuf的集成.

 

netty本身提供的protobuf demo展示了如何方便的与protobuf的集成方式.

 

对于每种客户端消息,需要找到对应的业务逻辑处理单元.而作为JavaEE开发者,习惯于使用spring来管理这些逻辑处理单元.在spring管理的bean上可以,轻松的添加业务监控功能.服务逻辑上需要使用一种方法来将消息和业务bean映射起来.这里使用了一种比较讨巧的方式来处理,将消息类型作为bean的名称.

 使用javameody监控spring beans

比如对于clientRequestType类型为LOGIN_REQUEST的报文.定义了LoginRequestHandler来处理:

@Component("LOGIN_REQUEST")
public class LoginRequestHandler extends AbstractRequestHandler {
@Override
    public void handle(ByteString packetData, Channel channel) throws InvalidProtocolBufferException {
        PBLoginRequest request = PBLoginRequest.parseFrom(packetData);//反序列化请求
.......
}
}

 这样在服务器收到报文后.可以方便的根据报文类型选择对应的handler来进行处理.

@Component
public class RequestDispatcher {
private Map<PBClientRequestType, RequestHandler> handlerMap = new HashMap<PBClientRequestType, RequestHandler>();

public void dispatchClientPacket(final PBClientPacket clientPacket, final Channel channel) {
PBClientRequestType clientRequestType = clientPacket.getClientRequestType();
try {
     handlerMap.get(clientRequestType).handleRequestData(clientPacket.getRequestData(), channel);
} catch (BadRequestException e) {
}
}

 以下是集成测试中,模拟客户端构造请求报文的代码:

 PBLoginRequest loginRequest = PBLoginRequest.newBuilder().setUsername(username).setPassword(password).build();
        PBClientPacket clientPacket = PBClientPacket.newBuilder().setClientRequestType(PBClientRequestType.LOGIN_REQUEST)
                .setRequestData(loginRequest.toByteString()).build();
channel.write(clientPacket );

  

TBD

分享到:
评论
5 楼 moqiaoxp 2014-08-03  
恩。思路不错,我已经基本实现了(未采用protobuf),后续考虑开源出来,另游戏开发加群讨论:142848600
4 楼 fanyun7654 2014-07-21  
楼主能更深入的交流下这个不,我现在需要做一个类似的东西。
3 楼 moqiaoxp 2014-01-07  
楼主,现在这个项目怎样了。
2 楼 朋在无锡 2013-11-12  
谢谢,每次来都有收获
1 楼 shootyou 2013-05-17  
follow,关注博主的后续更新~加油

相关推荐

    netty+protobuf (整合源代码)

    在《netty+protobuf 整合实战》中,作者通过实际的源代码展示了如何将这两个技术结合使用。首先,我们需要理解 Protobuf 的工作原理。 Protobuf 提供了语言无关的 .proto 文件来定义数据结构,然后通过 protoc ...

    基于netty+websocket+springboot的实时聊天系统项目源码.zip

    1、基于netty+websocket+springboot的实时聊天系统项目源码.zip 2、该资源包括项目的全部源码,下载可以直接使用! 3、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考资料...

    基于Netty+Redis+protobuf开发的即时通讯服务器

    基于Netty+Redis+protobuf开发的即时通讯服务器 第一版是一个简版,只实现了很少的功能,现在已经迁移到 [v1.0](https://github.com/linyu19872008/cdeer-im/tree/v1.0) 第二版的目标有以下几点: 1 工程用...

    netty+spring服务端-omen-1.1

    omen-1.1 自己基于netty开发的服务端,支持spring配置服务器启动模式:http,tcp,websocket等,并支持NIO和OIO方式,项目已应用于生产,可以通过jar形式加入其它项目,业务类实现业务service,启动不依赖于其他应用...

    基于springboot+netty+vue构建的类似bililbili的弹幕群聊系统,个人娱乐项目,可用于前后端开发学习研究

    基于springboot+netty+vue构建的类似bililbili的弹幕群聊系统,个人娱乐项目,可用于前后端开发学习研究 基于springboot+netty+vue构建的类似bililbili的弹幕群聊系统,个人娱乐项目,可用于前后端开发学习研究 ...

    毕设项目:基于netty+websocket+springboot的实时聊天系统.zip

    毕设项目:基于netty+websocket+springboot的实时聊天系统 毕设项目:基于netty+websocket+springboot的实时聊天系统 毕设项目:基于netty+websocket+springboot的实时聊天系统 毕设项目:基于netty+websocket+...

    netty+protobuf入门案例

    在"Netty+Protobuf入门案例"中,我们可以学习到如何结合这两个强大的工具进行高效的数据交换。首先,理解 Protobuf 的基本概念至关重要。 Protobuf 提供了一种定义数据结构的语言,通过编译器将这些结构转换为各种...

    基于Netty+TCP+Protobuf实现的Android IM库

    基于Netty+TCP+Protobuf实现的Android IM库,包含Protobuf序列化、TCP拆包与粘包、长连接握手认证、心跳机制、断线重连机制、消息重发机制、读写超时机制、离线消息、线程池等功能

    通信与协议Netty+Protobuf-游戏设计与开发(1)配套代码

    总结来说,"通信与协议Netty+Protobuf-游戏设计与开发(1)配套代码"是一个关于如何利用Netty进行网络通信以及如何使用Protobuf进行数据序列化的实例。通过学习这个资源,开发者可以更好地理解和掌握这两种技术在游戏...

    netty+protobuf开发一个聊天室实例

    在本文中,我们将深入探讨如何使用Netty和Protobuf来开发一个实时聊天室实例。Netty是一个高性能、异步事件驱动的网络应用框架,适用于Java平台,它简化了TCP、UDP和HTTP等协议的服务器和客户端应用开发。而Protobuf...

    springboot集成netty,使用protobuf作为数据交换格式,可以用于智能终端云端服务脚手架

    首先,Spring Boot 是一个基于 Spring 框架的轻量级开发工具,它简化了初始化和配置过程,使得开发者能够更快地启动和运行项目。通过集成 Spring Boot,我们可以利用其强大的依赖注入机制、自动配置特性以及丰富的...

    基于Netty+Redis+protobuf开发的即时通讯服务器.zip

    本项目"基于Netty+Redis+protobuf开发的即时通讯服务器"利用了三种技术:Netty作为网络通信库,Redis作为数据缓存与消息中间件,以及protobuf作为序列化协议,实现了高性能的实时通信解决方案。 首先,Netty是一个...

    基于netty+mqtt3.1.1+springboot+jdk8 实现的 mqtt 服务端跟客户端

    #### 已实现: * 发布订阅功能 * 遗言通知 * 会话session数据 * 发布保留消息 * 主题过滤(/test 会接受到 /test/yy 的主题消息) * 实现标准的 qos0 qos1 qos2消息确认机制 ... * 集成spring容器

    Netty4+ProtoBuf通信框架

    在这个项目中,客户端和服务端之间的通信是基于ProtoBuf协议进行的,通过maven项目管理依赖,提供startClient和startServer两个主要的入口类。 Netty是一个用Java编写的异步事件驱动的网络应用框架,特别适合用于...

    基于springcloud+Netty+MQ+mysql的分布式即时聊天系统.zip

    基于springcloud+Netty+MQ+mysql的分布式即时聊天系统.zip基于springcloud+Netty+MQ+mysql的分布式即时聊天系统.zip基于springcloud+Netty+MQ+mysql的分布式即时聊天系统.zip基于springcloud+Netty+MQ+mysql的分布式...

    netty+protobuf入门案例.

    Netty和Protobuf是两种在IT领域中广泛使用的开源技术,尤其在开发高效、高性能的网络应用程序时。本文将深入探讨这两个技术,并结合一个入门案例,帮助初学者理解如何将它们结合起来使用。 Netty是一个高性能、异步...

Global site tag (gtag.js) - Google Analytics