用于实时多人游戏的Node.js UDP

我正在使用node.js构build一个基于浏览器的实时多人游戏。 目前,我有客户端通过socket.io发送用户input到游戏逻辑服务器,游戏世界的快照发送回客户端进行渲染。

以下是代码的简化版本。 是否有可能使用UDP从基于浏览器的客户端发送数据到服务器,反之亦然? 我知道Node.js有一个UDP模块,但我不确定如何以这种方式来实现它。

任何帮助,将不胜感激。 谢谢。

服务器:

var server = http.createServer(handler).listen(8888); var iosocket = io.listen(server); // request/response handler function handler(req, res){ ... } iosocket.sockets.on('connection', function(socket){ console.log("[x] Socket listener started"); socket.on('msg', function(data){ console.log( " [-] incoming message); }); }); ... iosocket.sockets.emit("message", msg); 

客户:

 <!DOCTYPE html> <html> <head> <title>Test</title> <script type="text/javascript" src="/socket.io/socket.io.js"></script> <script type="text/javascript"> socket.on('connect', function(){ console.log("connected to server"); }); socket.on('message', function(message){ console.log('received message'); }); </script> </head> <body> <canvas id='canvas' width="400" height="400">Canvas</canvas> </body> </html> 

通常,浏览器不支持UDP连接。 具体来说,一些浏览器呢。 Google Chrome有一个socket API:

http://developer.chrome.com/trunk/apps/socket.html

[2012/10/29编辑为sockets不再是实验性的 – PhilH]

你也可以使用本地客户端接口的套接字API(不确定,只能猜测)。

如果你打算在不久的将来在浏览器上做任何事情,Websockets可能是你最好的select,但那些只是TCP。

关于你对UDP与TCP速度的评论,UDP总是会更快。 TCP提供了订购和交付保证(这意味着可能的重试和保留其他数据包,直到丢失的数据包最终到达目的地),而UDP只承诺发送一次,而不是关心后来会发生什么。 UDP只发送一次数据包,你需要弄清楚它是否丢失了。 当/如果您收到大量的UDP数据包时,如果顺序很重要,则需要将其编码到数据有效载荷中以便能够计算出来。

一般来说,对于那些丢失一些通常不重要的数据包,以及只有最新数据包真正重要的数据包来说,UDP会很好。 一个游戏可能通常使用一个TCPstream,其中sorting和保证传送很重要(重要的东西),UDPstream对象的移动等(只有最新的位置真的很重要,如果一个更新丢失了,只要每个包包含全部位置[而不是所有包都重要的delta))。

对于你自己的游戏,我build议先在TCP上实现它,然后当你有更多的经验时,你可以尝试把时间关键的东西(命令和丢失数据包的问题)转移到单独的UDPstream中。 有许多项目失败了,因为人们先从UDP开始,然后尝试在订单和交付保证上加上螺栓,有效地尝试重新实现TCP。 这就是为什么这样做更有意义。

实时应用程序通常是接收至less30 Hz的数据更新,抖动小于10%的应用程序。 TCP / IP是可靠的,但不能以这样的速率发送定期更新,而不会偶尔出现抖动。 这是因为TCP握手和确认确保可靠的传输,阻碍了周期性的快速更新。 UDP是一个简单的协议,其中套接字数据是火,忘记。 这本身就是一个问题,但是这个问题比TCP / IP的抖动问题更容易克服。 根据我的经验,UDP是唯一的出路,为什么实时应用程序会在VoIP中使用的RTP等协议中使用它。

Web套接字也是虚假的希望,因为这是一个基于TCP的协议。 我使用自定义的UDP套接字,其中发送者和接收者维护一个序列号,可以告诉你,如果数据包丢失,重复或无序,广域网上的所有问题。 find使用UDP并testing入站数据包的方法来衡量性能。

 var server = require('http').createServer(); require('dgram-browserify').listen(server); server.listen(8080);