13

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

下面是代码的简化版本。是否可以使用 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>
4

3 回答 3

24

通常,浏览器不支持 UDP 连接。具体来说,某些浏览器会这样做。谷歌浏览器有一个套接字 api:

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

[2012/10/29 编辑为套接字不再是实验性的 - PhilH]

您也可以使用来自本机客户端接口的套接字 API(不确定,只是猜测)。

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

关于您对 UDP 与 TCP 速度的评论,UDP 总是更快。TCP 提供排序和传递保证(这意味着可能会重试并保留其他数据包,直到丢失的数据包最终到达其目的地),而 UDP 只承诺发送一次,而不关心它之后会发生什么。UDP只会发送一次它的数据包,你需要弄清楚它是否丢失了。当/如果您收到大量 UDP 数据包时,如果顺序很重要,您需要在数据有效负载中对​​其进行编码才能弄清楚。

一般来说,UDP 非常适用于丢失一些通常无关紧要并且只有最新数据包真正重要的数据包。游戏通常可以使用 TCP 流,其中订购和保证交付很重要(重要的东西),以及 UDP 流用于对象移动等(只有最新位置才真正重要,如果一个更新丢失,只要每个更新都没有关系包包含完整位置[而不是所有数据包都重要的增量])。

对于你自己的游戏,我建议先在 TCP 上实现它,然后当你有更多经验时,你可以尝试将时间关键的东西(顺序和丢失的数据包不太重要)移动到单独的 UDP 流中。有很多项目都失败了,因为人们首先从 UDP 开始,然后尝试在其之上添加订购和交付保证,有效地尝试重新实现 TCP。这就是为什么反过来做更有意义。

于 2012-07-10T12:39:35.940 回答
1

实时应用程序通常是接收至少 30 Hz 且抖动小于 10% 的数据更新的应用程序。TCP/IP 是可靠的,但不能以这种速率发送定期更新,而不会偶尔出现抖动。这是因为 TCP 正在握手和确认以确保可靠传输,这妨碍了发送快速定期平滑更新。UDP 是一个更简单的协议,其中套接字数据是触发后忘记的。这本身就是一个问题,但这个问题比 TCP/IP 的不良抖动更容易克服。以我的经验,UDP 是唯一的前进方式,也是实时应用程序在诸如 VoIP 中使用的 RTP 等协议中使用它的原因。

Web Sockets 也是错误的希望,因为它是基于 TCP 的协议。我使用自定义 UDP 套接字,其中发送方和接收方维护一个序列号,它可以告诉您数据包是否丢失、重复或乱序,以及 WAN 网络上的所有问题。寻找使用 UDP 和检测入站数据包来衡量性能的方法。

于 2017-07-11T22:35:58.653 回答
-6
var server = require('http').createServer();

require('dgram-browserify').listen(server);

server.listen(8080);
于 2013-08-27T04:58:15.547 回答