课程简介

本课程为机械工业出版社出版的图书《百万在线:大型游戏服务端开发》的电子版。

第一局部:学以致用(第1~4章),这部分介绍了Skynet引擎的应用办法及注意事项,以《球球大作战》的案例贯通其中,全面又详尽地分析了服务端结构设计、通信协议格局、数据表结构设计、断线重连等计划的核心技术。

第二局部:入木三分(第5~7章),这部分揭示了在多核时代采纳古代C++编写多线程TCP网络服务器的高效做法,以C++重写Skynet的案例贯通其中,应用大量图表,活泼翔实地形容Linux环境下的编程技术。

第三局部:各个击破(第8~11章),这部分列举了同步算法、热更新、防外挂等理论工程难题,并对其逐个击破,十分具备实用价值。只管本书以Skynet为例,但其同样实用于应用C++自研引擎的项目组,甚至是选用Erlang、Golang、Java的开发者。

关键词:

C/C++/Lua | Socket、TCP/IP、Protobuf | Linux开发环境 | 多线程、数据库、分布式 | 高并发、内存透露、热更新

残缺版本,能够返回UWA学堂查看《百万在线:大型游戏服务端开发》。

第1.1节 咱们简略介绍了从玩家的角度来看,一款网络游戏大都会波及的流程,在此过程中,藏在幕后的服务端做了很多事件,那到底做了哪些?此服务端零碎又是如何开发的呢?

服务端程序要承载很多玩家,性能是必须要思考的问题。那么,1.2.4节的程序可能承载多少玩家同时在线呢?

1.3大节介绍服务端程序要承载很多玩家,性能是必须要思考的问题。

对于中大型商业游戏来说,往往呈现全服爆满的景象(如图1-12),1000多人的承载量远远不够。依据游戏厂商的新闻稿可知,2012年《梦幻西游》最高同时在线玩家达到了270多万人;2016年《王者光荣》的同时在线玩家超过了300万人。既然单个程序的承载量无限,最间接的方法就是开启多个程序来进步承载量。


图1-12 玩家爆满的游戏画面示意图

1.4.1 多个程序协同工作

图1-13展现了一种由多个程序独特合作的服务端模型,图中程序A和程序B别离解决客户端音讯,程序C作为中转站,负责程序A和程序B之间的通信。每个程序均独立运行,能够将其部署在不同的物理机上,造成人造的分布式系统。


图1-13 多过程服务端示意图

阐明:为对立术语,本书中“服务端”代表整个游戏服务端零碎;“程序”“过程”或“节点”代表一个操作系统过程;“物理机”代表服务器,涵盖了实体服务器和云服务器。

只管单个程序还是最多承载1000余人,然而只需开启1000个程序,并将其安排在数百台物理机上,实践上就能够撑持100万玩家,总承载量得以进步。


1.4.2 三个档次的交互

在分布式构造中,数据的交互被分成了三个档次,如表1-2所示。这就要求开发者能对游戏业务性能做出正当的切分。在游戏中,有些性能是强交互的,有些性能是弱交互的。以MMORPG为例,同一个场景的角色交互很强,每走一步都要让对方晓得,能够在同一个程序中解决同一个场景逻辑;不同场景的角色交互较弱,只有聊天、好友、公会这些性能须要交互,能够将同一个服务器的玩家都放在同一台物理机上解决;不同服务器的玩家交互很少,能够放到不同的物理机上。


表1-2 不同交互场景的区别


1.4.3 搭个简略的分布式服务端

实践归实践,实际出真知。实现1.2.4节的“走路”程序是场景服务器的一项次要性能,只管一个场景只能撑持数十人,只有多开几个场景就可能反对更多玩家。本节将实现图1-14所示的分布式程序,零碎中有两个“走路”程序,别离代表兽人村落和森林两个游戏场景,客户端间接连贯角色所在的场景,玩家只能看到所在场景的角色,不同场景角色能够全服聊天。该程序可分成三个步骤实现。


图1-14 简略的分布式系统

第一步,编写聊天服务器。聊天服务器其实是转发服务器,它治理着场景服务器发来的连贯(见代码1-5中的scenes),只有收到场景服务器的音讯,它就会播送给所有的场景服务器。聊天服务器会监听8010端口,期待场景服务器连贯。

代码1-5 聊天服务器(Node.js)

(资源:Chapter1/3_chat_server.js)

var net = require('net');var scenes = new Map();var server = net.createServer(function(socket){    scenes.set(socket, true) //新连贯            socket.on('data', function(data) { //收到数据        for (let s of scenes.keys()) {            s.write(data);        }    });});server.listen(8010);

第二步,让场景服务器(“走路”程序)连贯聊天服务器。场景服务器即是服务端又是客户端,对于玩家来说,它是服务端,对于聊天服务器来说,它又是客户端。在“走路”程序的根底上,让场景服务器连贯聊天服务器(见代码1-6中的net.connect),当场景服务器收到聊天服务器发来的数据时,就会把它一成不变地播送给客户端。

代码1-6 场景服务器的局部代码,用于连贯聊天服务器(Node.js)

(资源:Chapter1/3_walk_server.js)

var net = require('net');//"走路"程序略 server.listen(8001);var chatSocket = net.connect({port: 8010}, function() {});chatSocket.on('data', function(data){    for (let s of roles.keys()) {        s.write(data);    }});

第三步,给场景服务器增加聊天性能(见代码1-7)。假如客户端除了发送“left”“right”等指令外,还会发送聊天文字,那么在收到聊天音讯后它会把音讯原样发给聊天服务器。整个音讯流程是:①场景服务器将聊天音讯发送给聊天服务器;②聊天服务器把音讯播送给所有场景服务器;③各个场景服务器别离将聊天音讯播送给场景中的所有玩家。

代码1-7 场景服务器解决聊天音讯的局部代码(Node.js)

(资源:Chapter1/3_walk_server.js)

    //接管到数据    socket.on('data', function(data){        ……        //更新地位        if(cmd == "left\r\n") role.x--;        ……        else {                 chatSocket.write(data);                return;            };            ……     });

当初能够进行测试了,先运行聊天服务器,再顺次运行两个场景服务器(假如监听的端口别离为8001和8002)。如图1-15所示,客户端A和B连贯第一个场景服务器,客户端C连贯第二个场景服务器,服务器中的小方块代表各个程序,方块中的数字代表该程序的监听端口。当客户端A走动时,因为A、B同在一个场景中,所以它们会收到挪动音讯,而客户端C不在同一场景中,因而它不会收到;若客户端A发送聊天信息“战神公会招人”,三个客户端都能收到。


图1-15 测试分布式服务端


1.4.4 一致性问题

分布式程序要解决很多异常情况。如果程序部署在不同物理机上,连贯不太稳固,须要解决好断线重连、断线期间的音讯重发,以及断线后过程间状态不统一的问题。图1-16展现的是因网络不畅通导致的异样情景,如果客户端A的玩家向客户端B的玩家购买道具,音讯须要通过程序C直达,因程序A和程序C之间的网络连接出现异常,呈现了客户端B的玩家被扣除了道具,客户端A的玩家却没失去道具的状况。程序A与程序C的网络连接异样,游戏性能受到了影响,就算一段时间后从新连贯上,两个过程的状态也可能会不统一。


图1-16 分布式程序的异样情景

一致性问题是分布式系统的一大难题,在游戏业务中,开发者个别会把一致性问题抛给具体业务去解决。对于图1-16所示的异常情况,须要给每个交易赋予惟一编号。程序C除了转发音讯,还须要记录程序A对每个交易的执行状态,如果转发失败,程序C要在稍后重发交易音讯,直到程序A胜利执行。而程序A也须要记录每个交易的状态,如果某个交易曾经胜利执行,则不再响应程序C发来的音讯,防止反复增加道具。

另外,治理数百台物理机、成千盈百个程序也不容易,第一,物理机多了,某一台出故障的可能性很大;第二,开启或敞开全副程序要花费很长时间。

本篇为《百万在线:大型游戏服务端开发》其中局部内容,残缺版本能够返回UWA学堂查看。

适宜读者

1、刚入行的服务端工程师

2、游戏公司开发岗位的求职者

3、对游戏开发感兴趣的高校学生

4、游戏开发爱好者

你将取得

1、充沛理解业务逻辑和底层框架的设计用意

2、立足实际的服务端学习思路,深入浅出

3、用理论案例贯通各知识点,在实践中学习

4、理解商业游戏的设计思路和实现办法