- A+
几个月前,我偶然发现了一个由Eric Li所写的有趣的文章,题为“优化WebSockets带宽”[ 1 ]。Eric 提到的WebSockets的出现使得开发HTML5游戏更容易。但是在3D游戏中为每个玩家提供位置和旋转数据要消耗大量的带宽.。Eric 做了一些计算,用几个常见实例说明需要多少带宽。
读了这篇文章后,我很激动,因为我一直在处理实时数据流的带宽优化,已经十三年了。我是Lightstreamer的CTO 和共同创始人,Lightstreamer是一个实时的Web服务器,我们最初创建是为了提供金融业的实时价格。同时,为网上金融交易创造了许多优化算法,在线游戏也可以适用。几年来,我们已经与世界各地的许多银行共同在做优化带宽和减少延迟的工作。所以,我认为Eric的文章是一个挑战,证明我们已经在过去的十年中开发的算法是否足够使多人游戏直接受益,包括MMOs,MMORPGs,和模拟3D虚拟世界。我来自实时财务数据的部门,不是一个游戏开发专家,但我认为,金融和游戏之间的“交叉互补”可以得到一些意想不到的好处。
我们决定做一个简单的3D多人游戏世界的在线demo,使用Lightstreamer实时同步,同时显示实际使用的带宽。我们增加了几个按钮,滑块控制,允许调整脚本参数和模拟任何情况的数据传输。
最终产生一个工具包(toolkit ),可以利用实验调整不同的游戏通信方案。demo的完整源代码是免费的,在GitHub上。
在这篇文章中,我将通过demo,告诉你如何使用它,解释底层是什么,并说明了一些先进的技术。如果你有兴趣知道如何优化网络传输,你可以跳到下面这段”在实时web栈采用的技术“。
在线demo的链接:
https://demos.lightstreamer.com/3DWorldDemo
你现在就可以用它了。demo
可以调整,以消耗大量的带宽和CPU。为此,我们必须限制连接的用户数量。如果你发现自己无法连接,请让我们知道,我们会尽量安排一些专门的demo线路。
序言
这是关于什么的演示:
· Web上的轻量化三维位置/旋转数据网络流
· 带宽优化和低延迟的数据传输
· 为每个客户端节流的动态自适应数据重采样
这个演示不是:
· 轻量化三维物理计算
· 轻量级的3D渲染
· 很酷的3D渲染
警告: 基于你选择的参数,你可以体验到高带宽、CPU或内存使用的情况。这样做是故意的,让你体验多玩家3D世界的多种复杂情况。
换句话说,我们展示了通过普通的Web协议的3D世界坐标的实时传输(HTTP和WebSockets)可以很容易的实现,包括通过任何代理和防火墙,和优化的数据流所需的带宽。我们没有把重点放在优化客户端世界的渲染(我们用Three js一个很好的库,适用了基本方式),也没有优化物理引擎本身。基本上,我们只是送货的,但我们很擅长;)
高效的HTML5 3D渲染,似乎Chrome和Firefox浏览器目前比其他浏览器表现更好。在任何情况下,随意适用任何浏览器,做你自己的测试都可以(包括移动浏览器)。
demo服务器位于美国(在俄勒冈Amazon的数据中心)。评价你所经历的延迟时应该考虑这一点。
demo可以在两种不同的工作模式下:
· 服务器端 模式 ,根据客户端的输入流,物理学是在服务器端计算。每一次改变每个对象的坐标返回给客户端。这意味着,不仅没有预测在客户端完成的,但也没有插值!这是一个极端的情况下,客户端只作为一个“愚蠢的渲染器”。
· 客户端 模式,物理计算 在服务器端和客户端。渲染是基于 物理计算(所有玩家的旋转和平移),由JavaScript客户端执行 。每个客户端接收实时 来自服务器的其他客户端 的命令(或 更确切地说,变化的速度矢量和角动量, )作为物理计算输入。
另外,客户端从服务器接收(服务器仍然计算物理学)位置和 所有对象的旋转数据对象。这样,客户可以同步与来自服务器端的权威物理数据 ,可以纠正任何漂移。它也可以阻止周期同步。在这种情况下,每个客户端将独立更新状态,但可能随着时间的推移而产生偏差。
在这两种模式的更多信息,阅读”网络物理“by Glenn Fiedler [ 2 ]。
如何使用演示
点击https://demos.lightstreamer.com/3dworlddemo。你会看到一些控件和一个3D虚拟世界的渲染,由一些漂浮的3D物体。你是红色的物体。其他的人类玩家的代表蓝色的物体,而白色的物体是机器人(他们的存在是为了让世界不那么孤独,如果你是那里唯一的玩家)。
图2)
![Web 3D多人游戏的同步优化](https://youxijia.net/wp-content/themes/begin/img/blank.gif)
现在,这既是实时性web的魔力…
打开另一个浏览器窗口,或不同的
浏览器,甚至在不同的计算机上,打开同一个地址(https://demos.lightstreamer.com/3dworlddemo)。你会看到同样的世界,完全同步。
页面中的所有控件的旁边有一个问号图标,它提供了详细的目的。在渲染框中,你有两个滑块控制相机变焦和摄像机视野。
如果你关闭渲染框,你还在那里,但是渲染算法会在客户端停止以节省CPU。
如何移动
你可以是利用键盘移动红色物体。打开命令框,知道用什么按键。主要的,你 可以在三个轴方向添加冲力和扭矩(旋转)。
如果你不使用键盘,只需用鼠标或手指按屏幕上的按键。屏幕上的按键 通过命令和渲染框中都可用。
你给的冲力越大,就能获得方向上更高的速度。
图3)
![Web 3D多人游戏的同步优化](https://youxijia.net/wp-content/themes/begin/img/blank.gif)
你的身份(IDENTITY)
身份框允许你改变你的昵称,广播你的信息,和选择你的世界。你会在“默认”世界的开始,但你可以传送到任何其他的世界。输入另一个世界的名字,无论是现有的(一个与你的朋友商定的名字)或新的。
图4)
![Web 3D多人游戏的同步优化](https://youxijia.net/wp-content/themes/begin/img/blank.gif)
如果有太多世界各地的用户的连接,你将在观察者模式。尝试进入另一个世界成为一个活跃的玩家。
矩阵(MATRIX)
打开矩阵查看实际的远程服务器传输的数据。换句话说,表显示实时的位置和旋转,实际上是在你的浏览器窗口接收到的数据流连接。
图5)
默认情况下,使用的是客户端物理引擎,这意味着只有一些周期性的世界同步服务器将会传递。这就是为什么你会看到数字矩阵中很少发生变化。阅读下面调整(TUNING)段落,来从根本上改变这种情况…
调整(TUNING)
调整框包含了大部分的演示的可调整参数,是为您提供的实际实验工具包。
图6)
![Web 3D多人游戏的同步优化](https://youxijia.net/wp-content/themes/begin/img/blank.gif)
当demo开始时,默认模式是客户端,用2秒同步。
在调整框,你可以很容易的在服务器和客户端模式之间切换。结果中,你在框的顶部看到可以看到动态变化的当前的带宽。移动到一个没有其他玩家的世界里,对整个页面使用的带宽信息是每个玩家所需的带宽的一个相当准确的估计。
当客户端模式下,你可以调整同步时间滑块,默认为2秒。
在服务器端的模式,更多的参数可以调整。通过选择输入数据的更新频率精度,你可以拥有真正的经历了一些Eric的文章中讨论的情况。你可以打开Matrix框,看到Matrix中的坐标变化的疯狂速度变化,甚至更多的乐趣。
首先,你可以通过“最大频率”滑块改变服务器更新频率。默认情况下,它是每个对象33次更新/秒。你可以增加了服务器端的物理引擎的时钟,它工作在100赫兹(100次更新/秒)。看一下改变最大频率时带宽的变化。
然后,你可以玩数据编码。你可以选择二进制字符串编码的坐标。在二进制编码的情况下,你可以切换单双精度。在字符串编码的情况下,你可以选择小数点后的位数(默认为8)。
最后,你可以选择允许下行信道的最大带宽(通过底部的滑块)。分配带宽后数据流进行重采样。尽量减少它,看流量越来越少。
结果(RESULTS)
现在我们可以模拟一些Eric的文章的场景描述。例如,让我们看一个用户(创建一个新的孤独的世界,看得到的带宽)。如果我们提供33次更新/
s的双精度浮点格式,当对象变化和在三个轴旋转,带宽消耗量约为5.6 kbps。
在这种情况下,一个固定长度1的十进制字符串或2位的十进制数字可能是足够的。这种编码,带宽减小至约3.6 kbps。
但这些都是最坏的情况下,所有七个坐标都变化(在所有三个轴的平移和旋转)。如果这些坐标不改变,或不经常变化,Lightstreamer自动使用delta传递特征只发送变化的数据。例如,一个单一的对象是X轴上移动,用字符串的编码,2位数,33更新/秒,我们得到了一个关于带宽的使用1.5
kbps。
Lightstreamer优化算法的更多信息在下面的“在实时网络协议栈采用的技术“。
引擎之下
Demo中Lightstreamer被用作全双向的,双流向的、实时数据传输。更简单地说,Lightstreamer是一种特殊的Web服务器,可以发送和接收客户端(浏览器,移动应用程序,桌面应用程序,等等)更新的连续流。使用web网络协议(即HTTP和WebSockets)。基于发布/订阅模式的一种形式,它适用于实际的数据流的一些优化,而不是作为一个“哑管道”。
这个demo是由一些客户端代码和服务器端代码组成。
在客户端,应用纯HTML和JavaScript开发。源代码在GitHub。客户端使用JS库下面:
· jQuery控制
· Three js 3D渲染
· Lightstreamer实时数据传输和矩阵(matrix)部件。
在服务器端,两Lightstreamer适配器由java开发。适配器,作为Lightstreamer的插件,用于服务器接收,定制,和发送消息。适配器的源代码在GitHub上。该适配器使用croftsoft代码库用于物理计算。
因此,3D物理引擎是建立在服务器端作为Lightstreamer 的java适配器。适配器持有在游戏中的所有玩家位置和旋转数据,并按照可配置为100
Hz的频率重新计算。
客户端发送用户的命令(键盘)通过 Lightstreamer向服务器发送消息。每个用户也可以改变她的昵称和
在任何时间发送消息给其他玩家(这意味着demo包含一个基本的聊天功能)。
客户端接收到的实时数据通过订阅Lightstreamer服务,使用订阅模式(见章节”消息路由“和”不同的订阅模式”了解更多):
·
有一项对每个世界的服务(事实上,有一项为每个世界组合和表示精度,这是简单的解释)。这个服务是以命令模式和提供世界玩家的动态列表来工作,标示玩家进入和离开这个世界,也通知昵称变化和聊天信息。
这个服务包含字段:“key”(每个玩家的唯一标识符),“commond”(添加、更新或删除),“nick”(现在的昵称),和“msg”(当前聊天信息)。
·每个玩家进入一个世界,一个特定的服务由服务器创建(由客户订阅)为所有玩家进行实时坐标和运动。这项工作合并模式是每个世界中客客户端订阅/退订的,基于接收到的命令作为上面提到的第一项服务。
这个对象的字段是:
坐标和四元数,代表当前对象的位置:
“POSx”、“POSy”、“posz”、“rotX”、“rotY”、“rotZ”、“rotW”
以上字段订阅服务器模式,获得实时的位置和渲染的物体。它也订阅客户端,得到周期性权威的重新同步数据(除非重新同步时间设置为“从不”)。
matrix 部件使用这些字段,成为Lightstreamer的DynaGrid部件。
-速度矢量和角动量,它代表当前对象的运动:
“Vx”、“Vy”、“Vz”、“momx”、“momy”、“momz”
此字段是订阅客户端模式,接收客户端的物理引擎输入。
·
每个客户端订阅一个不同的模式的项目。换句话说,玩家通过保持激活这个订阅来标示它的存在。离开页面,则自动退订,服务器可以让其他玩家都知道用户已经离开(利用上面提到的命令模式项)。
· 每一个客户订阅合并模式的一个项目,以了解当前的下行带宽(使用自己的实时连接)。
你被鼓励去研究此demo的源代码,查看
GitHub,并从中得到你能想到的任何可能的工作。例如,你可能会附加一个统一的前端,你可能想要创建一个真正的游戏,或者你可以创建一个移动应用程序。
Lightstreamer可以为很多不同的客户端技术提供代码库。你可以下载Vivace版Lightstreamer,包含了一个免费的非过期的许可证允许20个连接的用户。
在实时web栈采用的技术
一些技术和功能要求,作为实时web栈的一部分,帮助游戏开发商在一个简单的,可靠的以及可优化的方式实现多人交流。让我们看看其中的一些,钻研得更深一点。
动态节流
有许多类型的数据,它可以通过他们自己的本性过滤(即采样)。当一个数据源提供了有一定的物理特性的一系列实时采样,你可能要降低采样频率,如果你不需要所有的样品。假设你有一个传感器测量当前温度每秒100次,你要将测量的数据实时到软件应用。如果你只向一个用户展示数据,也许10每秒更新足够多了。或者,更好的是,你可能想尽可能保持链路带宽的不饱和状态。
重采样一个实时数据流是一个复杂的过程,需要考虑几个变量作为输入:所需的最大频率,所需的最大带宽和可用带宽。
回到我们的3D虚拟世界,当服务器端由大量物理计算,大量的数据是让所有的客户在与世界同步更新。如果服务器端的物理计算工作在100赫兹,在许多情况下,你不需要或不能以相同频率发送数据到所有客户。你想发送尽可能多的更新,基于每个客户端连接的实际可用带宽。
在Developer Community pages of Valve[ 3 ](一些著名的3D游戏引擎),你看:
客户通常都只有有限的可用带宽。在最坏的情况下,玩家与调制解调器连接,不能接受超过5到7 kb
/秒。如果服务器试图发送更新和更高的数据速率,数据包丢失是不可避免的。因此,客户已经告诉服务器的传入带宽容量设置控制台变量(字节/秒),这是客户端最重要的网络参数,必须正确设置一个最佳的游戏体验。
这是自动完成的,Lightstreamer动态支持。由于其采用节流算法(起源于金融行业),Lightstreamer能够为每个用户重新采样数据,考虑到所有的动态变量:
·
带宽分配:为每一位客户,最大带宽可以分配给它的复用流连接。这样的配置可以随时改变和Lightstreamer保证它总是起作用,无论原始数据流的带宽。
·
频率分配:每一个数据流(订阅,在Lightstreamer条款)每个客户的复用流连接,最大的更新频率可以分配。再次,这样的配置可以在任何时间改变。
· 真正的带宽检测:自动检测网络拥塞和Lightstreamer不断适应实际的可用带宽。
Lightstreamer试探性地结合了这三类信息进行动态节流数据流重新采样。在我们的3D世界的demo,你可以看到这一切在行动。在调整框,切换到服务器端。“最大带宽”和“最大频率”滑块允许您控制带宽分配和实时频率分配。数据流进行相应的。现在,试着移动到一个不可靠的网络。或者用你的平板电脑或智能手机连接,通过3G(或者,更好的,2G)和移动到一个地方,手机信号不是很强。换句话说,你应该发现一些数据包丢失和带宽的萎缩。Lightstreamer将检测缓冲的更新和作为过期数据回放,它将开始重采样和自动降低频率和带宽。
基本上,每一个客户都会发现它带宽的使用的甜点,同时还接受新的数据。接受不频繁的更新并不意味着接收旧的更新。当你有机会得到一个更新的,它必须是可获得的最新数据,而不是一块前一段时间的数据缓冲。Lightstreamer能做到。将新鲜的数据即使在小的带宽,通过重采样的数据流,而不是排队。你可以看到一个活生生的例子关于简单的带宽和频率的演示(https://demos.lightstreamer.com/bandwidthdemo)。
重采样效果好于合并。合并意味着不是简单地丢弃更新,当进行重采样,发送人应尽量合并保存尽可能多的信息。让我们澄清一个例子。在3D世界中的demo,作为一个对象的坐标订阅的一部分,7变量被传递(3位置和4个旋转),你可以在矩阵框看到。现在,让我们考虑到只有3个位置,为了简单起见,假设这个序列的更新原始数据流:
1. X=5.1; Y=3.0; Z=2.3
2. X=unchanged; Y=3.1; Z=2.5
3. X=5.3; Y=unchanged; Z=2.8
如果重采样算法决定掉落事件2,叠加机制会产生一个单一的更新替换事件3,如下:
X=5.3; Y=3.1; Z=2.8
正如你看到的,事件2,进行y更新,还没有完全丢弃,但已与3事件混为一谈。
在订阅的合并模式,合并是Lightstreamer默认启用的。
这意味着你可以产生数据在任何频率,并且让Lightstreamer自动和透明地重采样然后合并在单个连接传递。
TCP和UDP
TCP通常被认为是当实现一个游戏的通信层一个糟糕的选择。拥塞控制机制和自动转发的订单交付可能导致游戏性能的退化。举几个例子:从文章本文由台湾大学[ 4
],一个MMORPG的协议进行比较,显示TCP的缺点。Glenn Fiedler写了[ 5 ]:
使用TCP是在开发网络游戏最糟糕的错误!要知道为什么,你需要看看TCP实际上在IP所做的,使一切看起来那么简单!
我不同意这些观点,他们完全有道理,但我想介绍另一个视角。
我们看下TCP与UDP的优点:
1. 它是可靠的(即使你不需要它,最好是有它,当然,这要付出的代价不太高)。
2. 如果是Web协议(HTTP和WebSockets),它可以通过任何代理、防火墙和网络中介。
因此,它将能够使用TCP甚至游戏是好的。Lightstreamer,利用HTTP和WebSockets,使用TCP,它试图克服一些智能算法的局限性。我不是说这里有了TCP
UDP,Lightstreamer就神奇有效…但我真的认为它对于一些游戏足够了。让我们来看看。
Batching 和nagles算法
正如Glenn Fiedler所说的,选择TCP_NODELAY 选项(即禁用TCP
Nagle算法)是必须的。Lightstreamer,禁用nagles
后,使用自己的算法来决定如何将数据打包成TCP段。延迟和效率之间的权衡可以配置。你可以接受更大的数据包伪造和降低开销的最大延迟是什么(网络开销和CPU开销)?对于每个应用程序和游戏你应该能回答这个问题,其配置在Lightstreamer,max_delay_millis参数.
最高可接受的延迟,更多的数据可以被塞到同一个TCP段(batching),提高整体性能。在极端的情况下,你可以使用max_delay_millis =
0。
考虑提供实时市场数据的专业交易者,工作时由8屏幕并有矩阵式的阅读能力,类似于连接多人游戏…我们发现一个batching间隔30毫秒适用于大多数情况。
避免排队
真正的问题是TCP数据包的重传。如果一段丢失,新的数据在服务器缓冲区排队直到起始段实际交付。这引起了网络上的混乱,旧突发数据包发送出去,会带来小带宽的网络连续丢包的风险。
如上所述,如果更新的数据是可用的数据,已经产生但尚未发送到网络,Lightstreamer动态节流可以停止排队。基本上,当网络拥塞引起丢包,Lightstreamer开始重采样和数据更新的数据覆盖旧数据排队。
再次,这是基于金融市场数据发布的。你想看一个股票的最新价格。如果网络拥塞数据流,当网络再次可用,你不想去看回放的旧数据,你需要新的数据。
delta 传递
在Developer Community pages of Valve [ 3 ],你看到:
游戏数据压缩使用delta压缩,减少网络负载, 意味着服务器不给全世界同时发送,只有相对于上次的数据产生变化才会发送。每个数据包在客户端和服务器之间发送
,已知的数字被跟踪以保持跟踪他们的数据流。通常全(delta)快照只发送在游戏 开始时或客户遭受沉重的包丢失了几秒后。
delta
传递是Lightstreamer默认情况下使用的,因为它总是意味着减少对金融数据发送量。如果一个用户订阅了20个不同的领域,每个股票(价格、投标、询问,时间,等),它们中每次只有少数会变化。Lightstreamer自动提取delta
,客户端库能够重建全状态。在连接初始,Lightstreamer发送一个完整的所有订阅事项的快照。即使在断开的情况下,客户端库的Lightstreamer自动重新连接和恢复状态,获得一个完整的快照。
流量感应
这个 documentation of Unity[ 7 ](一种最常用的3D渲染引擎)说:
连接服务器和客户端,是一个复杂的过程。机器可以有私人或公共的IP地址,他们有本地或外部防火墙阻止访问。统一网络的目的是处理许多情况下尽可能但没有通用的解决方案。
流量感应是一个奇特的名字,我们用Lightstreamer指使用TCP的能力自动检测最佳的传输协议。WebSocket是最好的选择,但在现实的世界里很多种情况下WebSocket不起作用。除了浏览器的支持,真正的问题是,一些网络中介(防火墙、代理服务器、缓存、NAT、等),不适用WebSockets并阻止他们。在所有这些情况下,Lightstreamer自动切换到HTTP流媒体,像WebSockets一样将数据从服务器到客户端的通信效率。但也有一些情况下,HTTP流是由一些公司代理受阻。在这种极端的情况下,Lightstreamer仍然通过自动切换到HTTP智能轮询(又名长轮询)。这与传统的轮询的方式非常不同,如轮询频率是动态的、数据驱动的。看
this slide deck [ 6 ]详情。
图7)
![Web 3D多人游戏的同步优化](https://youxijia.net/wp-content/themes/begin/img/blank.gif)
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsCBE9.tmp.jpg
对于许多应用,通过智能轮询提供用户体验和WebSockets一样。对于游戏,能够在超严格的企业防火墙后运行,即使少帧,比什么都没有要好。在这种情况下Lightstreamer提供智能轮询进行重采样,混合,和带宽管理。所以,在每个轮询周期,保证您收到新的数据。
我们已经提到的情况,在网络(包括所有的中介机构)中使用智能轮询。但还有Lightstreamer另一种情况,智能轮询自动使用。即使网络支持流(基于HTTP或WebSocket),数据流的发生率可能是客户端的处理能力太高。这尤其适用于老设备不能保持高频数据流的步伐。在这些情况下,Lightstreamer客户端库可以自动检测客户端代码不会快到需要排队,决定改用智能轮询。这样,实际的更新率将由客户驱动一批批新事件和请求。后续批次进行合并。虽然这听起来可能很奇怪,在这种情况下,智能轮询可以甚至超过WebSocket。互动游戏,投票,甚至在其它智能的形式,用流更好。但是,能够发挥在非常严格的企业防火墙后面稍微降低服务质量是聊胜于无。
所选的传输对应用程序是完全透明的(游戏),不需要采取任何特殊行动来使用。
要知道,传输是当你连接到3D世界的demo使用,只是滚鼠标指针放在左上角的“S”标签。标签将向右滑动,显示实际运输(WebSocket或HTTP流或轮询方式)。
图8)
![Web 3D多人游戏的同步优化](https://youxijia.net/wp-content/themes/begin/img/blank.gif)
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wpsCBEA.tmp.jpg
client-to-server in-order保证消息传递
和你所知相反,HTTP流没有任何额外的开销,相比比发送信息从服务器到客户端的WebSocket
通信。相比HTTP流,WebSocket的真正的好处是当你需要时发送消息从客户端到服务器。原因是,HTTP,发送消息时是从客户端到服务器,通过任何标准的Web浏览器来管理,有三个主要的局限性:
1. 它需要为每个消息全往返(除非HTTP 限流开启 ,这是在大多数浏览器默认关闭)。
2.
没有控制消息排序,多个消息可能会在多个连接上发送。这是通过HTTP连接池逻辑的浏览器没有信息暴露于JavaScript层。所以,即使你从您的JavaScript代码(2
HTTP请求)发送并列的两个消息,他们可能在网络会超越彼此。
3.
没有控制连接复用。正如上面所说,浏览器已经在连接池的独家控制,通常关闭空闲连接超时后。所以,如果有时间,你需要发送一个低延迟更新到服务器后,你必须建立一个新的TCP连接,从而增加了延迟。
Lightstreamer实现了一个抽象层,因此消除了以上三个问题,即使使用HTTP作为传输协议。特别的,Lightstreamer行为如下:
1. 它自动批量高频客户端的消息。这意味着,如果客户想在一阵交付100的消息,而不是发送100个HTTP请求,浏览器会发送一对HTTP请求。
2. 客户信息自动编号。服务器可以发送ACK为每个消息和排序顺序错乱。在控制确认消息的自动重传机制的客户端。换句话说,浏览器内部某种“TCP over
HTTP“已实现从客户端得到可靠服务器消息!
3. 反向的心跳可以激活所以浏览器保持连接打开,准备一旦需要使用。反向的心跳都是由客户端发送强制浏览器避免关闭底层的TCP连接的消息。
这些层的优化,保证信息从客户端到服务器端。这将需要使它非常可靠和支持高频通讯。这一层是通过一个很容易接触到应用层SendMessage函数调用。
轻量协议
给定一个传输(由流感应机制选择)和数据模型(见下面的消息路由协议),需要将完整数据传输到客户端。Lightstreamer避免使用JSON或者,更糟的是,XML,作为其协议的基础。这些都是非常冗长的协议,产生大量的冗余数据,(例如,字段名),从而增加带宽的使用。
Lightstreamer采用基于位置协议,从而降低了开销降至最低。节省大量的带宽。
下面是3D世界demo一个例子中获得的网络传输数据,在服务器端使用字符串编码模式。在这种情况下,一个基于js的协议,虽然不是JSON。其他的协议是可能的。
D(27,1,2,' 18.85667 ',3,'0.91879 ',' 0.39474
',1);D(30,1,5,’0.70090’,1,’0.71325’,’59.00561’);D(31,1,3,'27.42105 ',' 0.00389
',' 0.44682 ','0.89365 ',' 0.04139 ',1);D(29,1,3,' 57.12912 ',' 0.00389 ','
0.44682 ','0.89365 ',' 0.04139 ',1);D(28,1,2,'42.71763’,1,’0.40773’,'0.48877 ','
0.05785 ',' 0.76909 ',’7.72828’);
消息路由
实施优化和可靠的传输和协议,对于开发复杂的实时应用和游戏是不够的。在这种机制的顶部,你需要一个简单和灵活的方式路由信息,即治理的信息应该交付给客户端。
Lightstreamer是基于我所说的不对称的发布订阅范式.客户可以订购物品,可以发送消息到服务器,但实际的出版商在服务器端。基于任何后端数据供给,任何后端数据计算的算法,和从客户端收到的任何消息,出版商(Lightstreamer数据适配器)将实时更新的任何物品到Lightstreamer服务器。然后,由服务器根据客户端订阅更新。
图9)
在3D世界demo中,数据适配器包含游戏引擎。基于从客户收到的运动命令(通过SendMessage设施),计算物理变化和发布更新。
客户端订阅是基于项目和图式(itemsand
schemas)。例如,在3D世界demo中,如果一个客户想知道一个物体的实时位置,将订阅一个特定的项目,它表示对象,使用模式如下:
"posX", "posY", "posZ", "rotX", "rotY", "rotZ", "rotW"
让我们假设客户对知道的坐标和速度矢量感兴趣。它将订阅相同的项目但有不同的架构:
"posX", "posY", "posZ", "Vx", "Vy", "Vz"
如果客户想知道的昵称和其他球员的消息,除了被通知玩家进入和离开一个世界,它将订阅的主要项目(代表世界),用这样的模式:
"nick", "msg", "key", "command"
基本上,每一个客户端可以订阅许多需要的项目,每个都有其自己的模式。
图10)
![Web 3D多人游戏的同步优化](https://youxijia.net/wp-content/themes/begin/img/blank.gif)
因此,该Lightstreamer服务器多路复用所有订阅项目的每一个客户在同一物理连接上的更新。
图11)
![Web 3D多人游戏的同步优化](https://youxijia.net/wp-content/themes/begin/img/blank.gif)
客户可以订阅和退订的任何项目,在其生命周期的任何时间,不中断的复用流连接。
Lightstreamer使用按需出版模型只有当一个项目是被客户端首次订阅,数据适配器(出版商)被通知开始分发数据。然后,进一步的,客户端可以订阅相同的项和Lightstreamer服务器负责广播更新所有。当最后一个客户端退订项目,数据适配器被通知停止发布数据项目。这种方式,没有实际的受体存在,不需要产生数据,节省系统资源。
这个项目是基础的方法,Lightstreamer支持所有的路由方案,:广播,多播,和单播。例如,如果100万个不同的客户订阅相同的项目,数据适配器需要发布更新一次,和Lightstreamer服务器会执行巨大的风扇。另一方面,每个客户端可以订阅自己的个人项目,从而交付个人信息。好事情是不同的路由方案可以混合在一起,作为同一个多路复用连接部分。
图12)
![Web 3D多人游戏的同步优化](https://youxijia.net/wp-content/themes/begin/img/blank.gif)
在游戏中,这种灵活的发布和订阅模型,使得它更容易控制哪些数据应达到每个玩家。
可扩展性
管理大型多人在线游戏的实时数据,非常高的可扩展性是流媒体服务器的需要。Lightstreamer采用并行阶段事件驱动架构与非阻塞I/O。这意味着在服务器线程数和连接数的完全解耦。池中的线程数自动调整基于CPU核数。
这种结构允许对服务质量优雅降级。换句话说,在极端的情况下,服务器的CPU最好,游戏将不会被突然卡住,但所有的用户会稍微延迟,接收频率较低(但仍然是新的)更新。
在Lightstreamer的可扩展性的主要驱动力是整体的信息吞吐量,超过总连接数。例如,一个服务器实例成功地测试了一百万个连接的客户端,每一个连接信息率低(几更新每分钟)。通过增加信号频率可以为每客户端增加每秒消息数,并发客户机管理,由一个单一的数目减少到几万。
几个Lightstreamer服务器实例可以通过任何Web集群负载均衡设备,以达到更高的可扩展性。这应该使高频的大型多人在线游戏变得很容易地在一个更具成本效益的方式部署。
结论
我们提出了一个在线demo演示了如何创建一个金融业技术,可以在游戏行业也获得巨大的好处。自适应流媒体(动态节流、合并、delta传递,等)是一组技术,确保需要同步的3D虚拟世界,客户实时数据量是由每一个客户的实际网络容量决定。几个低级别的优化和高层次的抽象进行多人游戏的开发提供可靠的结果更容易。如果你想有效地解决实时游戏的问题,你应该在你的实时网络协议栈使用类似的技术。
此demo的源代码可以在GitHub上。随意修改和创作任何衍生作品;也许是一个全面的游戏!如果你找到演示代码有用,如果你将工作在基于它的任何项目,请让我们知道。我们渴望任何反馈。
往期精选:
本文由蛮牛译馆倾情奉献,除合作社区 及合作媒体外,禁止转载。
蛮牛社区(manew.com)分享最新的游戏研发和虚拟现实相关技术内容。