游戏之网络进阶

陷阵之志,有死无生 --赵信

如大家对网络还不甚了解,请先参照本系列网络介绍博文 游戏之网络初篇

现在很少有游戏公司自己用原生Socket API手写网络框架了,一是增加工作量,增加产品开发时长;二是如果综合性能、效率、高吞吐量、高并发,及稳健性来说,自己如果非大神,写出来的很可能还没别人已有的网络框架好,自己还需经大量测试验证才能保证线上稳定,不容出错。所以,现在很多的Java游戏框架,基本上都是用Netty或Mina作为网络通信框架的,Netty和Mina用起来有很多相似之处,知其一另一个上手就很容易,但在很多人看来,Netty比Mina更好用(更适合游戏使用),其一,Java游戏公司基本都是用Protobuf作为协议工具的,以应对游戏各种功能玩法中前后端所需不同的数据字段读取和传输要求,及减少协议联调出错几率,Netty包中自带对Protobuf的编解码器,而Mina还需自己去实现Protobuf的编解码器;其二,Netty比Mina更好地支持多种协议,比如对Http的支持,Netty就比Mina好些,在《游戏之网络初篇》中,游戏常用的协议Netty都支持,简直为游戏量身打造;其三,Netty比Mina更易使用,除了Netty自带很多编解码器外,在对ByteBuf的操作比Mina的IoBuffer的操作更简易,此外,Netty支持ByteBuf零拷贝,一听就是让人省心的提高效率和节约内存的高科技东东。

Netty 和 Mina都为韩国Trustin Lee开发出来的,这也是它们很多相似之处的原因之一。它们都是优秀的异步事件驱动,NIO(非阻塞)网络框架,获得了成百上千的商业项目验证。当然,在游戏开发中,也是锦上添花。

Protobuf 是谷歌的Protocol Buffers的简称,它是一个轻便高效存储和读取结构化数据的工具,用于结构化数据和字节码之间互相转换(序列化、反序列化),非常适合用于网络传输,且支持多种编程语言。游戏中使用Protobuf可以减少协议联调出错的几率,因为一旦使用Protobuf作为协议工具,当定好协议后,开发人员只管设置相应字段值即可,如果担心字段漏传,就用required限定即可;但是如果用其他的协议工具,那么开发人员除了设置相应字段值外,可能还需要正确设置字段长度,及字段顺序。

Netty的 ByteBuf 和 Mina的 IoBuffer 都是对JDK的 ByteBuffer 的高级封装,比起JDK的ByteBuffer,它们都支持动态扩展(而扩展JDK的ByteBuffer只能新建复制),且修复了JDK的众多NIO bug(比自己用原生JDK NIO API更少bug);但是 Mina的IoBuffer和JDK的ByteBuffer都只有一个标识位置的指针position,切换读写的时候要自己手动调用flip()和rewind()等,用起来稍微麻烦,而Netty的ByteBuf使用readerIndex和writerIndex分别维护读操作和写操作,实现读写索引分离,更加直观。

本文假设读者已对Netty有初步的了解,如知道Netty的大致框架(后续可能会补一些Netty的介绍文章),了解Netty的核心组件的关系及其作用,了解消息处理的大致流程。下面放图两张供读者回忆Netty基本知识点(摘自《Netty实战》),其余需更详细了解Netty的建议细读何品翻译的《Netty实战》和李林锋的《Netty权威指南》,更细节的需要读者自己钻研了。

netty核心组件.png

Netty核心组件的关系如下:【

  • 一个 EventLoopGroup 包含一个或者多个 EventLoop;
  • 一个 EventLoop 在它的生命周期内只和一个 Thread 绑定;
  • 所有由 EventLoop 处理的 I/O 事件都将在它专有的 Thread 上被处理;
  • 一个 Channel 在它的生命周期内只注册于一个 EventLoop;
  • 一个 EventLoop 可能会被分配给一个或多个 Channel。
    注意,在这种设计中,一个给定 Channel 的 I/O 操作都是由相同的 Thread 执行的,实际
    上消除了对于同步的需要。】

注意上面【】中引用《Netty实战》的最后一句,即“一个给定 Channel 的 I/O 操作都是由相同的 Thread 执行的,实际
上消除了对于同步的需要。”,虽然Netty中是这样,但在实际游戏开发中,因为一个EventLoop管理多个Channel,而每个EventLoop上所有的I/O却只由一个Thread处理,这就相当于多个客户端的I/O请求都由一个Thread处理了,这明显同一时刻可能阻塞其他客户端了,所以在实际游戏开发中,每个Channel的I/O操作(即每条协议请求),都会再放到一个逻辑线程池中处理,这样避免阻塞其他客户端,哎呀,一不小心剧透后面游戏框架博文的内容了,具体详情请见后续框架解读吧。

netty消息流程.png

以上是I/O操作的流程示意图,实际中ChannelPipeline中的入站和出站handler都是类似如下添加的

bootstrap.handler(new ChannelInitializer<ServerSocketChannel>() {
            @Override
            protected void initChannel(ServerSocketChannel ch) throws Exception {
                ChannelPipeline pipeline = ch.pipeline();
                pipeline.addLast("http_codec", new HttpClientCodec());
                pipeline.addLast("http_aggregator", new HttpObjectAggregator(65536));
                pipeline.addLast("protobuf_decoder", new ProtoDecoder(null, 5120));
                pipeline.addLast("server_handler", new ProtoServerHandler());
                pipeline.addLast("protobuf_encoder", new ProtoEncoder(checkSum, 2048));
            }
});

本文的原来标题是《Netty+Protobuf实现游戏的TCP通信》,本来是想一篇文章即介绍完这个话题的,但发现因为想引入Netty和Protobuf的简介导致文章太长了,不简介又担心新手读者没有个承上启下的因果关系导致强行去理解Netty和Protobuf实现TCP通信显得略为僵硬,所以本文标题还是改为《游戏之网络进阶》算了,旨在对游戏中使用Netty和Protobuf有个大致的介绍,而实际上Netty的内容还远不止本文刚说的那一丁点,想想李林锋大神那两本Netty的书就知道了,希望读者能自己去钻研细读,广思集益,从而对游戏的网络框架有更好的了解。

通常,了解一个大众使用的框架的规则,比自己手写类似功能更为迅捷和靠谱,在现在快节奏的游戏更新迭代中,快速开发一款游戏成为节约成本,取得市场先手优势的先决条件。但这并不鼓励只是一味的“拿来主义”而不推崇自己的主观动手能力了,实际的技术沉淀还需我们自己不断拓展加深,说不定哪天一个很好的框架就出自这样动手能力极强的读者手中了。下篇博文可真正进入《Netty+Protobuf实现游戏的TCP通信》了,敬请阅读。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 227,022评论 6 528
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 97,760评论 3 412
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 174,687评论 0 373
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 62,318评论 1 307
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 71,112评论 6 405
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 54,645评论 1 320
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 42,724评论 3 435
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 41,885评论 0 285
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 48,387评论 1 330
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 40,368评论 3 354
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 42,506评论 1 365
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 38,063评论 5 355
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 43,759评论 3 343
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 34,150评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 35,414评论 1 281
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 51,080评论 3 386
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 47,494评论 2 370

推荐阅读更多精彩内容