在线游戏,或者比 ajax 更快的东西来发送/接收数据

Posted

技术标签:

【中文标题】在线游戏,或者比 ajax 更快的东西来发送/接收数据【英文标题】:Online gaming, or something faster then ajax for sending/receiving data 【发布时间】:2012-09-30 15:29:50 【问题描述】:

我会尽量简短。

到目前为止我做了什么: 我的游戏将使用 setTimeoutsetInterval 使用 javascript 运行。这不是闪光或任何特别的东西。到目前为止,我所做的就像一个测试运行(这样你可以更好地理解),几乎是循环 Ajax 以尽可能快地向 php 页面发送请求,然后 PHP 从 url 中读取 $_GET请求,然后 PHP 使用$_GET 编辑一个名为 p1.html 的文件,这只是玩家 1 的 x 和 y 轴坐标。所以在玩家 2 的浏览器中,它和我上面说的差不多,现在当它收到 Ajax 请求时,它会收到玩家 1 的坐标。所以 JavaScript 做它所做的,并在玩家 2 的浏览器上移动玩家 1。那是我自己制作的,我对其进行了测试,是的,它可以工作,是的,当我修复所有错误和东西时,它会永远持续下去。

这么说,这就是我目前所做的,但如果我想要一款在线格斗游戏或实时横向卷轴游戏,这还不够快。所以这就是我需要帮助的地方。我知道 w3schools.com 上的很多东西,但我就是不知道如何完成这项工作。大概就是这样。我只需要浏览器 1,将数据发送到浏览器 2,类似于“1,100,200”或实际上更长一点,并让浏览器 2 将该数据作为 JavaScript 中的变量读取(任何类似于 x="received data"; 的东西),仅此而已。 JavaScript 将完成剩下的工作。

我确信我可以自己编程我需要的一切,但是对于从 A 点到 B 点每秒发送 50 次数据,我对此一无所知。连名字都没有。最后,网址和示例会非常好(更清楚)。特别是如果它已经在 w3schools.com 上(带有示例)而我只是错过了它。

【问题讨论】:

w3fools.com 【参考方案1】:

您可以使用websocket

WebSockets(优于 AJAX)的优势基本上是 HTTP 开销更少。建立连接后,所有未来的消息传递都通过套接字而不是新的 HTTP 请求/响应调用。因此,您会假设 WebSockets 每单位时间可以发送和接收更多的消息。事实证明这是真的。但是,一旦您将延迟添加到混合中,就会有一个非常痛苦的现实。

WebSockets 比 AJAX 快大约 10-20%

source

当我们在 php 中使用 ajax 时会发生什么

    它打开一个到 apache 服务器的新连接 比 apache 寻找 php 脚本并启动它 现在 php 脚本将连接到服务器进行查询并返回结果。

但是 websocket 所做的是消除了 2 个连接进程,并且只会向服务器发送一条消息。服务器已经连接到sql server

另一个好处是客户端和服务器之间的连接保持打开状态,服务器可以向客户端发送消息。在ajax中你每次都需要调用

【讨论】:

比这更好的是,websockets 允许推送数据并且不需要定期轮询(请参阅其他答案) 实际上这完全取决于您如何使用它们:P【参考方案2】:

答案很简单:使用websockets。它们允许在两个方向上立即推送数据,以实现看似即时的交互。它们消除了从缓慢而繁重的客户端(包括服务器)提取数据的需要。请注意,这是my favorite game 中用于通知推送的解决方案。

您可能对this introduction on websockets on PHP 感兴趣。但请注意,对于长连接处理和实时游戏(您可能更喜欢 Go、node.js、java 等),PHP 确实不是最有效的解决方案。

【讨论】:

【参考方案3】:

我同意其他发帖者的观点:websockets 是您应该使用的技术。唯一的缺点是 Internet Explorer 版本 10 之前不支持 Websockets,目前仅适用于 Windows 8,并且不适用于 Windows 7 之前的任何 Windows 版本。当你想在 Vista 和 XP 上支持 IE 用户时,您需要使用 AJAX 或 Flash 进行后备。

但是你可能会遇到另一个问题:

用于从 A 点向 B 点发送数据,例如每秒 50 次

当您需要频繁发送数据时,您的协议似乎有问题。您是否计划以 20 毫秒的固定间隔更新玩家位置,即使他们没有改变(玩家站立)或以恒定速率改变(玩家朝一个方向行走)?我建议你不要转移位置,而只改变移动方向(开始向左移动,在 X:Y 处停止向左移动等),这样可以保证大量带宽。

【讨论】:

微软官方告知 ie 使用不安全 Do you plan to update the player positions at regular intervals of 20ms even though they didn't change - 鉴于当前的设计(轮询,而不是推送)数据需要传输,即使说“什么也没发生”,否则 B 点永远不会知道 A 点何时有更新。跨度> 通过 AJAX 推送可以使用一种称为“AJAX 长轮询”的技术来完成。它的工作原理是延迟 AJAX 响应,直到有东西要发送。 ***.com/questions/333664/… only changes in movement direction 我刚刚意识到这就是为什么当您与许多流行游戏断开连接时,您的玩家角色会继续向某个看似随机的方向逃跑的原因。说停止运行的事件从未收到。 这也是许多流行游戏允许速度hack的原因:由于网络抖动(不可靠的延迟),发送准确的停止位置很重要,否则客户端和服务器将很快变得异步。但是当服务器盲目地信任停止位置时,客户端可以发送比游戏机制允许的更远的停止位置。防止这种服务器端并不像看起来那么简单,因为客户端和服务器之间的微小时间差异在在线环境中是很自然的。要检测速度黑客,需要采用启发式方法。【参考方案4】:

如果架构正确,long polling ajax 请求可以很好地用于非实时通信。话虽如此,长轮询更像是一种“黑客”;如果您正在寻找具有所需连接性的内置,那么您的选择肯定是websockets:

WebSockets 是一种先进的技术,它可以打开一个 用户浏览器与 服务器。使用此 API,您可以将消息发送到服务器并接收 事件驱动的响应,无需轮询服务器以获取回复。

查看browserquest 以获得灵感 - Mozilla 的优秀人员提供了其完整源代码on github!

【讨论】:

【参考方案5】:

试试这个:http://socket.io/

它可以做 websockets、长轮询、flash sockets 等等! 他们声称它支持 IE 5.5。

【讨论】:

【参考方案6】:

Websockets 很棒,并且经常被提及,但是 android 设备和 16% 的浏览器不支持 websockets (CanIUse.com)。许多服务器安装也不支持 websocket,包括共享 LAMP 设置。如果您有共享主机或想要获得广泛支持,websockets 可能不是一个有效的选择。

长轮询是 websocket 的唯一有效替代方案。它有更广泛的支持(它应该适用于几乎所有的服务器和客户端),但它在不能很好地处理许多同时连接的服务器上(比如 Apache)有一个明显的缺点。另一个缺点是,无论连接了多少用户,您都必须执行许多常规数据库查询(可能每秒几次)。使用共享内存,如 PHP 中的shm_attach(),可以减轻这种负担。当服务器脚本监视新消息时,一旦发现它们就会立即通过打开的连接发送。客户端将收到消息,然后通过新请求重新启动长连接。

如果您不能使用 websockets(很可能是这种情况),您可以使用长短轮询混合(见下文)。使用非常长的轮询是不必要的,并且会占用太多资源。在持续连接大约 10 或 15 秒后,您应该将其关闭并切换到老式的短轮询,这只是一个重复的常规 GET 请求。

这个 jQuery 代码未经测试,但你明白了:

function longpoll(lastid) 
    /* Start recursive long polling. The server script must stay
    connected for the 15 seconds that the client waits for a response.
    This can be done with a `while()` loop in PHP. */

    console.log("Long polling started...");

    if (typeof lastid == 'undefined') 
        lastid = 0;
    

    //long polling...
    setTimeout(function () 
        $.ajax(
            url: "stream.php?long=1&lastid=" + lastid, success: function (payload) 
                if (payload.status == "result") 
                    //result isn't an error. lastid is used as bookmark.
                    console.log("Long poll Msg: " + payload.lastid + ": " + payload.msg);
                    longpoll(lastid); //Call the next poll recursively
                 else if (payload.status == "error") 
                    console.log("Long poll error.");
                 else 
                    console.log("Long poll no results.");
                

                /* Now, we haven't had a message in 15 seconds. Rather than 
                reconnect by calling poll() again, just start short polling 
                by repeatedly doing an normal AJAX GET request */

                shortpoll(lastid); //start short polling after 15 seconds

            , dataType: "json"
        );            
    , 15000); //keep connection open for 15 seconds
;

function shortpoll(lastid) 

    console.log("Short polling started.");

    //short polling...
    var delay = 500; //start with half-second intervals
    setInterval(function () 
        console.log("setinterval started.");
        $.ajax(
            url: "stream.php?long=0&lastid=" + lastid, success: function (payload) 
                if (payload.status == "result") 
                    console.log(payload.lastid + ": " + payload.msg);
                    longpoll(lastid); //Call the next poll recursively
                 else if (payload.status == "error") 
                    console.log("Short poll error.");
                 else 
                    console.log("Short poll. No result.");
                
            , dataType: "json"
        );
        delay = Math.min(delay + 10, 20000) //increment but don't go over 20 seconds    
    , delay);

短轮询减少了并发连接的数量,而是使用重复轮询(请求)。与往常一样,短轮询的缺点是延迟获取新消息。但是,这类似于现实生活,所以应该没什么大不了的。 (如果有人在过去一周内没有给你打电话,他们不太可能在接下来的五分钟内给你打电话,所以每五分钟检查一次你的手机是很愚蠢的。)

【讨论】:

以上是关于在线游戏,或者比 ajax 更快的东西来发送/接收数据的主要内容,如果未能解决你的问题,请参考以下文章

游戏服务器应该如何接收具有定义滴答率的 udp 数据包?

Ajax 原生底层代码

JQuery之Ajax

为啥 UDP + 一个软件可靠的订购系统比 TCP 更快?

基于ChatGPT的API实现一个响应速度比官方更快的在线问答网站并通过宝塔上线全网可访问

基于ChatGPT的API实现一个响应速度比官方更快的在线问答网站并通过宝塔上线全网可访问