现在用nodejs做游戏服务器开发教程的多吗

您所在的位置: &
使用Node.js开发多人玩的HTML 5游戏(1)
使用Node.js开发多人玩的HTML 5游戏(1)
布加迪编译
《星噬》确实引起了我的兴趣,因为它很简单,但玩法很吸引人,不过明显缺少支持多人玩的功能。我一下子来了劲,想解决这个问题。于是,osMUs(MU指多人玩)应运而生,这是一款基于浏览器的多人玩的《星噬》克隆版游戏。
【51CTO精选译文】有一天,几个朋友来我家,给我介绍几个很酷的iPad游戏。其中一个游戏是《星噬》(Osmos),开发这款游戏的是加拿大一家独立开发商,名叫Hemisphere Games。你可以控制在二维空间漂浮的一个小小的星团。小星团唯一能做的事就是往某个特定的方向喷射自己,结果往相反的方向推动星团。游戏规则很简单;主要规则就是,两个星团碰撞时,大的那个会吞噬掉小的那个。其余规则基本上直接来自质能守恒。
《星噬》确实引起了我的兴趣,因为它很简单,但玩法很吸引人,不过明显缺少支持多人玩的功能。我一下子来了劲,想解决这个问题。于是,osMUs(MU指多人玩)应运而生,这是一款基于浏览器的多人玩的《星噬》克隆版游戏。
浏览器浏览到osmus登录页面后,服务器会将宇宙的当前状态发送给新的客户端,这个宇宙由多个速度随机的星团组成。这时候,客户端可以被动地关注游戏进度;但是当然了,也可以作为玩家控制的星团,加入游戏。一旦玩家加入,他就可以点击或在移动设备上快速按下画布(canvas),射出新的星团。
随着游戏不断进行,服务器决定某人(可能是其中一个独立自主的星团)何时获胜;这时,玩家们接到通知,游戏重新开始。
本文其余部分介绍了与开发有关的一些具体内容。所以,如果你想试一下,尽管试好了。不过要注意一点:osmus在Chrome稳定版(版本13)和iPad上运行。
我编写osmus,是为了分成不同的、松散耦合的组件,既为了让其他代码贡献者更容易获得代码库,又为了便于尝试可以互换的技术。
osmus使用一个共享的游戏引擎(Game Engine),该引擎既可以在浏览器中运行,又可以在服务器上运行。引擎是一个简单的状态机,其主要功能就是使用里面定义的物理规则,计算出与时间有关的下一个游戏状态。
puteState&=&function(delta)&{ &&&var&newState&=&{}; &&&&&&return&newS &}&
这是游戏引擎很狭窄的定义。在游戏开发领域,游戏引擎的含意通常涵盖渲染器、声音播放器和网络层等方面。这种情况下,我在这些组件之间作了非常明确的划分,osmus游戏的核心仅仅包括物理状态机,那样客户端和服务器都能计算出下一个状态,因而在时间上做到很合理的同步。
客户端有三个主要部件组成:渲染器、输入管理器和声音管理器。我制作了一个非常简单的基于画布的渲染器,将星团画成红圆圈,将玩家星团画成绿圆圈。我的同事Arne Roomann-Kurrik编写了一个替代的基于three.js的渲染器,使用了一些壮丽的着色器和阴影。
声音管理器处理回放声音效果和背景音乐(来自8-bit Magic)的工作。目前实现的方法使用了音频标签,有两个元素,一个用于背景音乐通道,另一个用于声音效果通道。这个方法存在已知的局限性,但考虑到我实现的方法具有模块性,声音实现方法可以换成使用其他API的方法,比如使用Chrome的Web Audio API。
最后,输入管理器负责处理鼠标事件,但是可以换成改而使用触摸操作的管理器,用于移动版本。在移动情况下,可能有必要使用CSS3转换而不是使用画布,因为CSS3在iOS上是硬件加速的,而HTML5画布仍然不是,也没有实现WebGL。
说到移动,我惊喜地发现,osmus在iPad上玩起来很顺畅,尤其是在运行最新iOS版本的iPad 2上。这太好了,也是为开放互联网编写游戏的其中一个实际好处。
内容导航&第 1 页: &第 2 页:
关于的更多文章
Node.js是一个使用了Google高性能V8引擎的服务器端JavaScript实
网友评论TOP5
随着云计算、物联网、大数据、移动互联网的大发展,你应该知道这些。
谷歌Dart语言项目的领导人Lars Bak宣布推出编程语言Da
日,微软TechED 2011在北京万事达中心召
HTML5仿佛一夜间受到大多业内巨头的青睐,有点像《海
本书由浅入深地介绍Windows Forms编程的技巧和各种实用方法。本书先详细介绍了菜单、状态条、可复用类库、文件对话框、文本框、
51CTO旗下网站我是一只产品喵,喵喵喵~~~
不明白为什么说到nodejs就要跟前端扯上关系。稍有点开发经验的人都知道,前端做后端的门槛完全不是语言,而是思想。。。我做后端,直接用nodejs开发游戏服务器,没有任何阻碍,然而现在让我写前端web页面,我宁愿选择死亡。nodejs中,最重要的是一切都是异步,懂服务器开发,应该知道异步意味什么,至于callback带来的所谓 callback hell,那就是新手跟老手对待坑是一种怎样的处理方式了。还在以为nodejs只是玩具,是前端自我意淫可以写服务器的一个东西,我只能说,没了解过就别bb
已被提问者采纳
你还没有登录,请先登录或注册慕课网帐号
一般 大型的 公司 都是采用了多种编程语言 例如 阿里巴巴 吧
它就是采用了 jsp和 nodejs(当然 我就了解到 后端里面它用着这俩 至于还有没有其他的 我不清楚了)jsp稳定性 很强大
java 诞生了好多年了 稳定性 没得说 但是 java的性能讲真 不如 nodejs的 i/0处理方面强大 如果 淘宝 并发的 话 那nodejs 就会很大的提升 访问速度
你还没有登录,请先登录或注册慕课网帐号
虚心学习 。
天猫就是用的node吧。。
你还没有登录,请先登录或注册慕课网帐号
纸上得来终觉浅,绝知此事要躬行。
能啊,据说阿里双十一就用了node。
你还没有登录,请先登录或注册慕课网帐号
白日依山尽,兵长一米六
对数据安全要求高的 不会采用这种语言的 一般会采用JAVA
你还没有登录,请先登录或注册慕课网帐号
8264人关注
Copyright (C)
All Rights Reserved | 京ICP备 号-2用nodejs的实现原理和搭建服务器(动态)
投稿:jingxian
字体:[ ] 类型:转载 时间:
下面小编就为大家带来一篇用nodejs的实现原理和搭建服务器(动态)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
今天是我学习的Node.js的第二天,所谓的node.js其实它是javascript编写的服务器的语言,同时它又是属于后台的框架,是一个开放性的平台。
一、相关理论知识:
我们可以用requre来引入模块、用module.exprorts来导出模块。
安装nodejs和配置npm
1.安装nodejs,安装完后在cmd命令行中敲入node -v,查看版本。
2.在cmd中敲入npm config list查看是否安装npm。
3.设置镜像地址。
淘宝镜像:在命令行中敲入npm config set registry=https://registry.npm.taobao.org
朗沃服务器镜像:在命令行中敲入npm config set registry=http://192.168.8.10:7001
安装express
1.初始化项目。命令:npm init
2.安装全局的express生成工具。命令:npm install express-generator -g
3.执行express命令生成项目的骨架。
4.在命令中输入npm install下载express依赖的所有插件。
5.使用npm start启动服务器。或者node app。
在输入上面的命令时,一定要仔细一点,不然容易敲错,同时在生成express时我们一定要先进入到某个具体的文件夹,再进行相应的操作。
下面是一些模块方法:
3、http.createServer是用来创建服务器
4、listen(填入一个应用程序的端口号)
5、res.end()& 这是我们在写node.js时必须加的一个结束方法
而它可发送一个字符串等任何数据,数组除外。
二、 node.js的相关操作
1、 node.js的实现原理:
简单的来说:node.js是当用户量很大的时候,服务端会把收到的用户信息放在事件队列中,再由事件队列机制对每一天用户请求进行处理,例如,利用回调函数,找到一个又一个想对应的方法就执行。然后处理完后就响应到浏览器上面。
2、 node.js的获取网页中的数据
1&get方法:
router.get('/login',function(req,res){
var username=req.query.
var pwd=req.query.
console.log(username,pwd);
res.send('登录成功');
2& post方法:
router.get('/login',function(req,res){
var username=req.body.
var pwd=req.body.
console.log(username,pwd);
res.send('登录成功');
在上面变量pwd=req.body.pwd,这里的pwd指的是form表单中name属性的值。
以上这篇用nodejs的实现原理和搭建服务器(动态)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具深入浅出node.js游戏服务器开发――基于Pomelo的MMO RPG开发 分享 - 谷普下载深入浅出node.js游戏服务器开发――基于Pomelo的MMO RPG开发点击复制内容
在上一篇文章中,我们介绍了如何使用lo来搭建聊天服务器。在这篇文章中,我们为大家介绍如何使用lo框架来搭建MMO RPG服务器,并分析其设计思路和实现方法。以此来帮助大家更好的理解和使用Pomelo框架,理解Pomelo框架的基础流程,使用方法和设计理念。本文中的服务端架构,只是为了说明Pomelo的理念和设计思路,并不是Pomelo开发的唯一方案,开发者完全可以根据自己的实际应用环境设计不同的服务端架构。开始之前Pomelo框架与MMO RPG我们曾在本系列第一篇文章曾介绍过pomelo的架构。我们先简单回顾一下Pomelo为我们的游戏开发提供了什么:作为Pomelo游戏开发的入门导引,本文的重点将放在游戏基础架构的搭建上,因此本文将主要介绍下面三个方面的内容:游戏服务端的构建,与的通讯,服务器的扩展。本文的参考示例我们使用demo Treasures作为本文的参考示例,游戏的截图如下:从上图可以看出,在treasures中,玩家会进入一张遍布宝物的地图中,通过拾取宝物来获得积分。所有玩家的积分在右上角会有一个。下面是这个demo的关键点:相对于一般的的MMO RPG,这个demo显得十分简陋:没有持久化,没有战斗,没有AI。。。但是,其中实现了MMO RPG中最核心的亮点功能:一个可以容纳多个在线玩家的游戏场景,以及玩家之间的实时互动。那些功能的确实可以让系统的结构更加清晰明确,成为一个非常好的项目导引。搭建游戏服务端由于游戏逻辑十分简单,我们后端采用一台单独的场景服务器来运行整个游戏逻辑,同时加入一台连接服务器来承载用户连接,系统的设计如下:下面,我们就按照这个设计来搭建游戏服务端。编写场景服务游戏场景是玩家所处的虚拟环境,而场景服务器就是游戏场景在服务端的抽象,根据游戏类型和内容的不同,场景服务器的复杂程度也会千差万别。在我们的例子中,场景的构成十分简单:一张开放的游戏地图,地图中的玩家,以及定时刷新的宝物。首先,作为一个场景服务器,需要能够储存用户和宝物的信息,这里我们直接使用一个放在内存中的map来储存场景中的所有实体,同时,我们将所有场景中的实体都抽象为一个Entity对象,放在这个map中。为了能够操纵这些数据,还需要暴露出对外接口,我们使用的接口有下面三种:我们通过一个循环的tick来场景服务,在每一个tick中会更新场景中所有实体的状态信息,我们最终设计如下:搭建场景服务器在完成场景服务的代码之后,我们还需要提供一个场景服务运行的平台,在Pomelo中,我们通过搭建一个场景服务器来实现。Pomelo中的服务器分为两类,负责承载用户连接的前端服务器和运行逻辑的后端服务器。作为负责核心逻辑的场景服务器,自然是属于后端服务器,因此,我们在/game-sever/config/server.json中加入以下配置: & & &area&: [ & & & {&id&: &area-server-1&, &host&: &127.0.0.1&, &port&: 3250, &areaId&: 1} & & ] 其中的“area”是我们为场景服务器类型所起的名称,其对应的内容就是场景服务器的列表,可以看出,现在我们只加入了单台场景服务器。与聊天服务器相比,场景服务器的配置并没有明显区别,只是多了一个areaId的属性。我们使用这一属性来标明这个场景服务器对应的场景id,我们的建议设计是一个游戏服务器对应一个独立的游戏场景,这样可以大大减少场景管理的开销,并提高单场景的负载能力。Pomelo中每一个服务器就是一个独立的进程,相对于一个场景服务的开销,单独的服务器造成的开销是可以接受的。当然,这只是建议设计,框架本身完全支持一个游戏服务器对应多个游戏场景的设计。开发者可以根据具体的应用情况调整场景服务器的配置,通过加入场景管理逻辑,实现一个场景服务器和场景之间的自由配置。启动场景服务在加入场景服务器之后,我们还需要对服务端的运行环境进行配置,在场景服务器启动时运行对应的场景服务。为了实现这一目标,我们需要在app.js中加入如下配置: & & app.configure('production|development', 'area', function(){ & & & var areaId = app.get('curServer').areaId; & & & area.init(dataApi.area.findById(areaId)); & & }); app.configure方法用来对指定的服务器进行配置,包括三个参数,前两个参数分别是运行环境和服务器类型的filter,第三个参数是在满足前面两个filter的情况下需要运行的代码。在上面的配置中,第一个参数&production|development&表示是针对线上和开发两种环境,之后的‘area’参数表示的是针对area服务器类型。 关于app.js初始化的更多内容,见Pomelo启动流程。与通讯建立连接服务器要与客户端通信,我们需要建立一个前端服务器,用来维护与客户端之间的连接。server.json中的配置如下: & & &connector&: [ & & & {&id&: &connector-server-1&, &host&: &127.0.0.1&, &port&: 3150, &clientPort&: 3010, &frontend&: true} & & ] &其中的标志位“frontend:true”表示这是一个前端服务器,“clientPort:3010”则表示该服务器对外暴露前端。对于前端服务器,在启动时就会默认加载连接组件,因此我们不需要在app.js中进行额外的配置。在pomelo 0.3中,如果需要使用原生websocket等非默认的连接方式,则需要在app.js中加入相应配置。在客户端,我们在启动时连接对应的接口,就可以建立起与服务端的连接。处理客户端请求Pomelo中,我们提供了两种客户端向服务端发送请求的方法,request/response模式和notify模式。request/response 模式与web中的请求模式相似,是标准的请求/响应模式,对于客户端的一个请求,服务端会给出一个响应。以玩家的为例,当需要时,会发送一个请求给服务端,服务端会验证客户端的请求,,并返回结果客户端,下图是具体请求流程:最上面的是客户端代码,在这里,我们向服务端发送一个移动请求。 之后,服务端会根据请求的route(area.playerHandler.move)找到对应的处理方法(/game-server/area/handler/playerHander.move),然后调用该方法来处理客户端的请求。当处理完成之后,会并在next方法中传入处理结果,结果会发回客户端,并作为回调函数的参数传回。
notify模式的运行流程与request/response类似,只是当服务端处理请求后不会发送任何响应。客户端通过pomelo.notify方法来发出notify请求,notify请求的参数与pomelo.request相似,只是不需回调函数,notify方法的实例如下:``` pomelo.notify('area.playerHandler.pick', params); ``` 服务端消息推送与web服务不同,game服务端会有大量的推送消息,要实现这一功能,我们使用pomelo中的push模式来实现。下图以“move”为例,展示了服务端的推送流程:Treasures中的广播功能是通过一个全局的channel来实现的,在游戏中的所有玩家在加入游戏后都会加入一个全局的channel中。当需要广播消失时,服务端就会调用这个全局的channel来对所有用户进行消息推送。扩展游戏服务端在前面两节中,我们使用pomelo搭建了一个单节点的游戏服务器。在这一节中,将介绍如何使用Pomelo来对服务端进行扩展,搭建分布式的游戏服务。由于游戏服务器的复杂性,像web服务器简单的水平扩展是不现实的,而根据业务逻辑的不同,不同的服务器也有着不同的扩展方案。因此我们分别以前面介绍的连接服务器和场景服务器为例,来对他们进行扩展。连接服务器的扩展连接服务器作用是负责维护所有客户端的连接,负责客户端消息的接受和推送,在MMO RPG中,连接服务器往往是性能的热点之一,因此对连接服务器的扩展对于提高系统负载有很重要的现实意义。 在例子treasures中,我们通过加入一个负载均衡服务器(gate服务器),来实现连接服务器的扩展:当客户端登录时,会首先连接gate服务器,来分配一个连接服务器,之后,客户端会断开与gate服务器的连接,在与其对应的连接服务器建立连接,如下图所示:要实现这一功能,在服务端,我们首先要在server.config中加入新的前端服务器,代码如下:``` "gate": [ {"id": "gate-server-1", "host": "127.0.0.1", "clientPort": 3014, "frontend": true} ] ``` 之后,在gate服务器上编写对应的负载均衡接口,在例子中,我们采用了使用uid的crc值对服务器数目取模的方式,代码如下:``` module.exports.dispatch = function(uid, connectors) {
var index = Math.abs(crc.crc32(uid)) % connectors.
return connectors[index]; }; ``` 最后,在客户端加入对应的连接代码,就完成了对连接服务器的扩展。 在我们的例子中只用到了两台连接服务器,而在实际应用中,可以根据实际环境,编写自己的负载均衡算法,加入更多的连接服务器。场景服务器的扩展与连接服务器不同,场景服务器中包含着大量的状态信息,如果对单一的场景进行扩展,需要复杂的同步机制和大量远程调用。因此,在Pomelo中,我们的场景扩展是通过加入新的场景来进行的。 在设计游戏时,整个世界就被分为多个不同的场景。而在服务器端,一个场景则与一个独立的场景服务器相对应,场景服务的扩展可以通过加入新的场景来完成。下面,就以treasure为例,介绍一下场景服务的的扩展方法: 因为场景扩展是通过加入新的场景来完成的,所以首先要在server.json中加入新的场景服务器:在加入场景服务器之后,我们还要保证发往场景服务器的请求可以被分发到正确的场景去。而Pomelo中,对于同一类型的服务器,默认的分法方法是采用随机分配的方式,这是不能满足我们要求的。因此,我们需要加入自己的路由算法,流程如下:首先,我们编写了新的路由算法:根据用户所属的场景id进行投递。之后,我们在app.js中使用app.route方法来将我们的路由算法配置为针对area服务器的默认方法。app.route方法接受两个参数,第一个是需要自定义route的服务器类型,第二个参数就是具体的路由算法。我们分别将‘area’服务类型和我们编写的算法传入,就可以实现自定义的路由功能了。跨平台客户端除了原有的JS客户端之外,pomelo还提供了多种其他的客户端,而不同的客户端可能会对应着不同的长连接协议。但是经过pomelo封装之后,在Pomelo服务端,不同客户端在连接上连接上是完全对等的。因此,你可以使用pomelo框架实现跨平台联机对战的(前提是你开发了针对多个平台的游戏客户端)。最终架构经过扩展后,我们的最终服务器架构如图所示:总结在本文中,我们介绍了如何使用Pomelo框架来构建了一个包括连接服务器和场景服务器的MMO RPG服务端。并介绍了如何使用pomelo特性,来对游戏服务端进行扩展,并构建出了一个分布式的MMO RPG服务。 但是,这只是游戏服务端开发中最为基础的部分,MMO RPG中很多基础功能在这里都没有实现,如数据持久化,AI控制,寻路系统等。在下面的文章中,我们会进一步介绍Pomelo在游戏开发中的应用。
来源:谷普下载3115人阅读
Linux(13)
Mysql(8)
J2EE(17)
游戏服务器概述
没开发过游戏的人会觉得游戏服务器是很神秘的东西。但事实上它并不比web服务器复杂,无非是给客户端提供网络请求服务,本质上它只是基于长连接的socket服务器。当然在逻辑复杂性、消息量、实时性方面有更高的要求。
游戏服务器是复杂的socket服务器。
如果说web服务器的本质是http服务器,那么游戏服务器的本质就是socket服务器。 它利用socket通讯来实现服务器与客户端之间的交互。事实上有不少游戏是直接基于原生socket来开发的。 相对于简单的socket服务器,它承受着更加烦重的任务:
后端承载着极复杂的游戏逻辑。网络流量与消息量巨大,且实时性要求极高。通常一台socket服务器无法支撑复杂的游戏逻辑,因此在socket服务器的背后还有一个服务器群。
为什么纯粹的socket服务器还不够好?
很多web应用不会基于原生的http服务器搭建,一般都会基于某类应用服务器(如tomcat)搭建,而且还会利用一些开发框架来简化web开发。 同样,一般游戏服务器的开发都会在socket服务器上封装出一套框架或类似的应用服务器。为什么使用原生的socket接口开发不够好呢?
抽象程度。原生的socket抽象程度过低,接口过于底层,很多机制都需要自己封装,如Session、filter、请求抽象、广播等机制都要自已实现,工作量很大,容易出错,且有很多的重复劳动。可伸缩性。高可伸缩性需考虑很多问题,消息密度、存储策略、进程架构等因素都需要考虑。用原生的socket要达到高可伸缩性,需要在架构上花费大量的功夫,而且效果也未必能达到开源框架的水准。服务端的监控、管理。很多服务器的数据需要监控,例如消息密度、在线人数、机器压力、网络压力等,如果采用原生socket,所有这些都要自己开发,代价很大。
用框架来简化游戏服务器开发
一个好的框架可以大大简化游戏服务器的工作。除了游戏自身的逻辑外,大部分的工作都可以用框架来解决。服务端的抽象,可伸缩性,可扩展性这些问题都可以通过框架来解决。 游戏服务器框架也承担了应用服务器的功能。可以把框架看成容器,只要把符合容器标准的代码扔进去,容器就运行起来了。它自然具备了抽象能力、可伸缩性和监控、管理等能力。
游戏服务器框架介绍
在开源社区里充斥了数不清的web服务器框架,游戏客户端的框架和库也有一大堆,但唯独游戏服务器框架少之又少,零星有一些类库,但完整的解决方案几乎没有。我们只好从商用的解决方案中拿出一些框架进行类比:
RedDwarf是唯一一个能找到的完整的开源游戏服务器框架,由sun出品。可惜在它合并到Oracle以后已经停止开发了。 在设计上,RedDwarf是个分布式架构,它在分布式数据存储和任务管理上投入了太多精力,而且做的过于理想化,如动态任务迁移功能的实现非常复杂,但实际应用中根本用不到。而在可伸缩性和性能的设计上不太理想。因此RedDwarf夭折了。
SmartfoxServer是由意大利的一家游戏公司gotoAndPlay()推出的商用游戏服务器。 它是基于java开发的,与web应用服务器如Tomcat看上去很类似。Smartfox支持各种客户端,且有一些成功案例。它在服务端封装和监控管理方面实现得很完善。 但在可伸缩性上并不是太理想,尽管Smartfox也支持Cluster模式,但它的扩展方式是基于jvm内存复制的。也没有实现传统MMORPG基于场景分区的解决方案。 Smartfox有免费版本,但完全不开源。而且它的免费版本(达不到高并发用户要求)很大程度是为了吸引开发者最终购买它的收费版本。不限在线人数的收费版本价格达到3500美刀。
Bigworld是澳大利亚Bigworld公司开发的全套3d MMORPG游戏解决方案,解决方案包含了客户端和服务端。Bigworld功能非常强大,在动态负载均衡和容错性做了很多工作。可扩展性非常强大。 它的缺点是过于重量级,对硬件要求高,且价格非常昂贵。Bigworld是专门为3d MMORPG游戏定制,但并不适用于中小型游戏的开发。
Pomelo是网易于2012年11月推出的开源游戏服务器。它是基于node.js开发的高性能、可伸缩、轻量级游戏服务器框架。 它的主要优势有以下几点:
开发模型快速、易上手,基于Convention over configuration的原则,让代码达到最大的简化。架构的可伸缩性和可扩展性好,pomelo在服务器扩展和应用扩展上实现得非常方便。轻量级,虽然是分布式架构,但启动非常迅速,占用资源少。参考全面,框架不仅提供了完整的中英文档,还提供了完整的MMO demo代码(客户端html5),可以作为很好的开发参考。
Pomelo目前的主要缺点是推出时间尚短,一些功能还在完善中,支持的客户端类型还有限,目前已支持HTML5、ios、android、untiy3d等4类客户端,未来还会支持更多的客户端类型。
游戏服务器的可伸缩性探讨
不管是web应用还是游戏服务器,可伸缩性始终是最重要的指标,也是最棘手的问题,它涉及到系统运行架构的搭建,各种优化策略。 只有把可伸缩性设计好了,游戏的规模、同时在线人数、响应时间等参数才能得到保证。
为什么游戏服务器的可伸缩性远远不及web?
相比web应用几乎无限扩展的架构(前提是架构设计得好),游戏服务器的可伸缩性相比就着差远了。那么是哪些因素导致游戏无法达到web应用的扩展能力呢? 说明:本文提到的web应用不包括类似于聊天这样的高实时web应用,高实时web可认为是一种逻辑较简单的游戏。
长连接和响应实时性
web应用都是基于request/response的短连接模式。占用的资源要比一直hold长连接的游戏服务器要少很多。Web应用能使用短连接模式的原因如下:
通讯的单向性,普通web应用一般只有拉模式响应的实时性要求不高,一般web应用的响应时间在3秒以内都算响应比较及时的。
而游戏应用只能使用长连接,原因如下:
通讯的双向性,游戏应用不仅仅是推拉模式,而且推送的数据量要远远大于拉的数据量响应的实时性要求极高,一般游戏应用要求推送的消息实时反映,而实时响应的最大时间是100ms。
在高并发长连接服务的解决方案中,目前除了传统的C语言(过于重量级)实现,用的最多的是erlang与node.js。两者的性能指标差不多,而node.js在易用性方面毫无疑问胜出太多。
最近微博上看到时go的能撑起100万的并发连接,node.js也能达到同样的数据,&有node.js的长连接数据,它占用了16G内存,但CPU还远没跑满。
交互的相邻性与分区策略
普通的web应用在交互上没有相邻性的概念,所有用户之间的交互都是平等,交互频率也不受地域限制。 而游戏则不然,游戏交互跟玩家所在地图(场景)上的位置关系非常大,如两个玩家在相邻的地方可以互相PK或组队打怪。这种相邻的交互频率非常高,对实时性的要求也非常高,这就必须要求相邻玩家在分布在同一个进程里。 于是就有了按场景分区的策略,如图所示:
一个进程里可以有一个场景,也可以有多个场景。这种实现带来了以下问题:
游戏的可伸缩性受到场景进程的限制,如果某个场景过于烦忙可能会把进程撑爆,也就把整个游戏撑爆。场景服务器是有状态的,每个用户请求必须发回原来的场景服务器。服务器的有状态带来一系列的问题:场景进程的可伸缩,高可用性等都比不上web服务器。目前只能通过游戏服务器的隔离来缓解这些问题。
游戏中广播的代价是非常大的。玩家的输入与输出是不对等的,玩家自己简单地动一下,就需要将这个消息实时推送给所有看到这个玩家的其他玩家。 假如场景里面人较少,广播发送的消息数还不多,但如果人数达到很密集的程度,则广播的频度将呈平方级增长。如图所示:
假如场景中1000个玩家,每人发1条消息,如果需要其它玩家都看到的话,消息的推送量将高达1,000,000条,这足以把任何服务器撑爆。
解决这个问题的方案:
减少消息数量---消息只发送给能看到的玩家。玩家能看到的只是屏幕的大小,而不是整张地图的大小,这样推送消息的时候可以只推给对自己的状态感兴趣的玩家。这个可以用AOI(area of interested)算法来实现,在pomelo的库pomelo-aoi中实现了简单的灯塔算法。分担负载,将消息推送的进程与具体的逻辑进程分离。如图:
这样广播逻辑与具体的进程逻辑就不会相互影响了,而且由于只有后端的场景服务器是有状态的,前端负责广播的服务器还是无状态的,因此前端服务器可以无限扩展。
实时游戏的服务端一般都需要一个定时tick来执行定时任务,为了游戏的实时性,一般要求这个tick时间在100ms之内。这些任务包括以下逻辑:
遍历场景中的实体(包括玩家、怪物等),进行定时操作,如移动、复活、消失等逻辑。定期补充场景中被杀掉的怪的数量。定期执行AI操作,如怪物的攻击、逃跑等逻辑。
由于实时100ms的限制,这个实时tick的执行时间必须要远少于100ms,因此单进程内很多数据都会受到限制。
场景内实体的数量受限制,因为要遍历所有实体注意更新的算法,所有的算法,包括AI在内都要在几十毫秒全部完成注意GC,full GC最好永远不要发生。一般full GC的时间都会高于100ms,幸好node.js在内存少于500M时表现良好,只有小GC。因此一定要控制内存大小。尽量分进程,进程的粒度越少,出现tick超时或full GC的可能越少。在多核时代里,CPU是最廉价的资源。
高可伸缩的运行架构
经过以上这些分析。我们可以得到现在的运行架构,如下图:
运行架构说明:
客户端通过websocket长连接连到connector服务器群。connector负责承载连接,并把请求转发到后端的服务器群。后端的服务器群主要包括按场景分区的场景服务器(area)、聊天服务器(chat)和状态服务器等(status),这些服务器负责各自的业务逻辑。真实的案例中还会有各种其它类型的服务器。后端服务器处理完逻辑后把结果返回给connector,再由connector广播回给客户端。 master负责统一管理这些服务器,包括各服务器的启动、监控和关闭等功能。
这个运行架构符合了刚才提到的几个伸缩性原则:
前后端进程分离,把承载连接和广播的压力尽量分出去。进程的粒度尽量小,把功能细分到各个服务器按场景分区
前面提到4个游戏服务器框架,只有bigworld和pomelo符合这样的架构,当然bigworld实现的还要更复杂。 现在的问题是,这个运行架构是个分布式架构,而且并不简单,那就带来以下问题:
需要多少的代码来实现这样的运行架构?服务器类型、数量管理和扩展有点复杂,该怎么管理?服务器之间会有一堆的相互rpc调用,实现起来怎么简化?分布式的开发和调试并不容易,消耗资源量过大,过于重量级,多进程bug定位困难,该怎么解决? Pomelo和node.js将很轻松地帮我们解决这些难题,我们下一节将讨论。
node.js、pomelo与游戏服务器
Node.js的特点与游戏服务器极其符合。列举如下:
对网络IO的处理能力,node.js生来就是为IO而生的,而游戏服务器刚好是网络密集型的应用。单线程的应用模型,node.js的单线程处理能力远比其它语言强大,而单线程处理游戏逻辑是最简单,最不容易出错,而且不可能出现死锁、锁竞争的情况。语言与轻量的开发模型。Javascript语言已经不是昔日的吴下阿蒙,它不仅由于脚本语言的轻量、简单带来了开发效率的提升。还可以与一些类型的客户端共享部分代码,如html5,unity3d的js客户端等。语言的动态性带来了很多框架设计的便利,如设计DSL,实现Convention over configuration。尽管这方面比ruby稍差,但在pomelo框架中使用已经足够好了。
Pomelo是基于node.js搭建的游戏服务器框架,它在灵活性、扩展能力,轻量级调试方面具有无可比拟的优势。我们先简单回答第三章最末的几个问题:
用pomelo来实现以上的运行架构几乎是零代码的,因为它在设计时天生就具备这样的架构。服务器类型、数量的管理极简单,利用鸭子类型、目录定义,只要一个简单json配置文件就可以实现所有服务器的管理。rpc调用可以实现完全零配置,也不用生成stub。感谢js语言的动态性,基于Convention over configuration的原则,可以直接实现rpc调用。分布式的开发和调试只占用很少的资源,启动极其迅速,十几个进程只用10秒不到的时间完全启动。多进程调试与单进程调试没有任何区别,只在一个console里搞定。
在本系列文章后面将会陆续讨论pomelo是怎么实现以上如此方便的特性, 以及这些设计带来的启发。
本文分析了游戏服务器框架的市场现状,一个高可伸缩游戏服务器架构的设计原则及运行架构。Node.js与pomelo在解决高并发和分布式架构中起到的作用。下文我们将深入分析pomelo在解决复杂的游戏服务器运行架构中提供了哪些便利。
原文地址q.com/cn/articles/game-server-development-2
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:324257次
积分:2590
积分:2590
排名:第12275名
原创:25篇
转载:38篇
评论:35条
(2)(1)(1)(1)(3)(3)(6)(1)(16)(3)(1)(3)(3)(2)(4)(2)(1)(6)(4)}

我要回帖

更多关于 nodejs 做游戏服务器 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信